comparison OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.cpp @ 4451:f4dbdb2dcba6

new configuration option "MaximumPduLength" to tune the maximum PDU length
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 18 Jan 2021 14:51:52 +0100
parents 4a4e33c9082d
children cb8fcecf1b02
comparison
equal deleted inserted replaced
4450:9bf2f9e0af47 4451:f4dbdb2dcba6
28 #include "../OrthancException.h" 28 #include "../OrthancException.h"
29 #include "../SerializationToolbox.h" 29 #include "../SerializationToolbox.h"
30 #include "../SystemToolbox.h" 30 #include "../SystemToolbox.h"
31 #include "NetworkingCompatibility.h" 31 #include "NetworkingCompatibility.h"
32 32
33 #include <dcmtk/dcmnet/diutil.h> // For ASC_DEFAULTMAXPDU
34
33 #include <boost/thread/mutex.hpp> 35 #include <boost/thread/mutex.hpp>
34 36
35 // By default, the default timeout for client DICOM connections is set to 10 seconds 37 // By default, the default timeout for client DICOM connections is set to 10 seconds
36 static boost::mutex defaultConfigurationMutex_; 38 static boost::mutex defaultConfigurationMutex_;
37 static uint32_t defaultTimeout_ = 10; 39 static uint32_t defaultTimeout_ = 10;
38 static std::string defaultOwnPrivateKeyPath_; 40 static std::string defaultOwnPrivateKeyPath_;
39 static std::string defaultOwnCertificatePath_; 41 static std::string defaultOwnCertificatePath_;
40 static std::string defaultTrustedCertificatesPath_; 42 static std::string defaultTrustedCertificatesPath_;
43 static unsigned int defaultMaximumPduLength_ = ASC_DEFAULTMAXPDU;
41 44
42 45
43 namespace Orthanc 46 namespace Orthanc
44 { 47 {
45 void DicomAssociationParameters::CheckHost(const std::string& host) 48 void DicomAssociationParameters::CheckHost(const std::string& host)
64 boost::mutex::scoped_lock lock(defaultConfigurationMutex_); 67 boost::mutex::scoped_lock lock(defaultConfigurationMutex_);
65 timeout_ = defaultTimeout_; 68 timeout_ = defaultTimeout_;
66 ownPrivateKeyPath_ = defaultOwnPrivateKeyPath_; 69 ownPrivateKeyPath_ = defaultOwnPrivateKeyPath_;
67 ownCertificatePath_ = defaultOwnCertificatePath_; 70 ownCertificatePath_ = defaultOwnCertificatePath_;
68 trustedCertificatesPath_ = defaultTrustedCertificatesPath_; 71 trustedCertificatesPath_ = defaultTrustedCertificatesPath_;
72 maximumPduLength_ = defaultMaximumPduLength_;
69 } 73 }
70 74
71 75
72 DicomAssociationParameters::DicomAssociationParameters() : 76 DicomAssociationParameters::DicomAssociationParameters() :
73 localAet_("ORTHANC"), 77 localAet_("ORTHANC"),
74 timeout_(0) // Will be set by SetDefaultParameters() 78 timeout_(0), // Will be set by SetDefaultParameters()
79 maximumPduLength_(0) // Will be set by SetDefaultParameters()
75 { 80 {
76 remote_.SetApplicationEntityTitle("ANY-SCP"); 81 remote_.SetApplicationEntityTitle("ANY-SCP");
77 SetDefaultParameters(); 82 SetDefaultParameters();
78 } 83 }
79 84
80 85
81 DicomAssociationParameters::DicomAssociationParameters(const std::string& localAet, 86 DicomAssociationParameters::DicomAssociationParameters(const std::string& localAet,
82 const RemoteModalityParameters& remote) : 87 const RemoteModalityParameters& remote) :
83 localAet_(localAet), 88 localAet_(localAet),
84 timeout_(0) // Will be set by SetDefaultParameters() 89 timeout_(0), // Will be set by SetDefaultParameters()
90 maximumPduLength_(0) // Will be set by SetDefaultParameters()
85 { 91 {
86 SetRemoteModality(remote); 92 SetRemoteModality(remote);
87 SetDefaultParameters(); 93 SetDefaultParameters();
88 } 94 }
89 95
137 return (localAet_ == other.localAet_ && 143 return (localAet_ == other.localAet_ &&
138 remote_.GetApplicationEntityTitle() == other.remote_.GetApplicationEntityTitle() && 144 remote_.GetApplicationEntityTitle() == other.remote_.GetApplicationEntityTitle() &&
139 remote_.GetHost() == other.remote_.GetHost() && 145 remote_.GetHost() == other.remote_.GetHost() &&
140 remote_.GetPortNumber() == other.remote_.GetPortNumber() && 146 remote_.GetPortNumber() == other.remote_.GetPortNumber() &&
141 remote_.GetManufacturer() == other.remote_.GetManufacturer() && 147 remote_.GetManufacturer() == other.remote_.GetManufacturer() &&
142 timeout_ == other.timeout_); 148 timeout_ == other.timeout_ &&
149 ownPrivateKeyPath_ == other.ownPrivateKeyPath_ &&
150 ownCertificatePath_ == other.ownCertificatePath_ &&
151 trustedCertificatesPath_ == other.trustedCertificatesPath_ &&
152 maximumPduLength_ == other.maximumPduLength_);
143 } 153 }
144 154
145 void DicomAssociationParameters::SetTimeout(uint32_t seconds) 155 void DicomAssociationParameters::SetTimeout(uint32_t seconds)
146 { 156 {
147 timeout_ = seconds; 157 timeout_ = seconds;
209 { 219 {
210 CheckDicomTlsConfiguration(); 220 CheckDicomTlsConfiguration();
211 return trustedCertificatesPath_; 221 return trustedCertificatesPath_;
212 } 222 }
213 223
214 224 unsigned int DicomAssociationParameters::GetMaximumPduLength() const
225 {
226 return maximumPduLength_;
227 }
228
229 void DicomAssociationParameters::SetMaximumPduLength(unsigned int pdu)
230 {
231 CheckMaximumPduLength(pdu);
232 maximumPduLength_ = pdu;
233 }
234
235
215 236
216 static const char* const LOCAL_AET = "LocalAet"; 237 static const char* const LOCAL_AET = "LocalAet";
217 static const char* const REMOTE = "Remote"; 238 static const char* const REMOTE = "Remote";
218 static const char* const TIMEOUT = "Timeout"; // New in Orthanc in 1.7.0 239 static const char* const TIMEOUT = "Timeout"; // New in Orthanc in 1.7.0
219 static const char* const OWN_PRIVATE_KEY = "OwnPrivateKey"; // New in Orthanc 1.9.0 240 static const char* const OWN_PRIVATE_KEY = "OwnPrivateKey"; // New in Orthanc 1.9.0
220 static const char* const OWN_CERTIFICATE = "OwnCertificate"; // New in Orthanc 1.9.0 241 static const char* const OWN_CERTIFICATE = "OwnCertificate"; // New in Orthanc 1.9.0
221 static const char* const TRUSTED_CERTIFICATES = "TrustedCertificates"; // New in Orthanc 1.9.0 242 static const char* const TRUSTED_CERTIFICATES = "TrustedCertificates"; // New in Orthanc 1.9.0
243 static const char* const MAXIMUM_PDU_LENGTH = "MaximumPduLength"; // New in Orthanc 1.9.0
222 244
223 245
224 void DicomAssociationParameters::SerializeJob(Json::Value& target) const 246 void DicomAssociationParameters::SerializeJob(Json::Value& target) const
225 { 247 {
226 if (target.type() != Json::objectValue) 248 if (target.type() != Json::objectValue)
230 else 252 else
231 { 253 {
232 target[LOCAL_AET] = localAet_; 254 target[LOCAL_AET] = localAet_;
233 remote_.Serialize(target[REMOTE], true /* force advanced format */); 255 remote_.Serialize(target[REMOTE], true /* force advanced format */);
234 target[TIMEOUT] = timeout_; 256 target[TIMEOUT] = timeout_;
257 target[MAXIMUM_PDU_LENGTH] = maximumPduLength_;
235 258
236 // Don't write the DICOM TLS parameters if they are not required 259 // Don't write the DICOM TLS parameters if they are not required
237 if (ownPrivateKeyPath_.empty()) 260 if (ownPrivateKeyPath_.empty())
238 { 261 {
239 target.removeMember(OWN_PRIVATE_KEY); 262 target.removeMember(OWN_PRIVATE_KEY);
277 300
278 result.remote_ = RemoteModalityParameters(serialized[REMOTE]); 301 result.remote_ = RemoteModalityParameters(serialized[REMOTE]);
279 result.localAet_ = SerializationToolbox::ReadString(serialized, LOCAL_AET); 302 result.localAet_ = SerializationToolbox::ReadString(serialized, LOCAL_AET);
280 result.timeout_ = SerializationToolbox::ReadInteger(serialized, TIMEOUT, GetDefaultTimeout()); 303 result.timeout_ = SerializationToolbox::ReadInteger(serialized, TIMEOUT, GetDefaultTimeout());
281 304
305 // The calls to "isMember()" below are for compatibility with Orthanc <= 1.8.2 serialization
306 if (serialized.isMember(MAXIMUM_PDU_LENGTH))
307 {
308 result.maximumPduLength_ = SerializationToolbox::ReadUnsignedInteger(
309 serialized, MAXIMUM_PDU_LENGTH, defaultMaximumPduLength_);
310 }
311
282 if (serialized.isMember(OWN_PRIVATE_KEY)) 312 if (serialized.isMember(OWN_PRIVATE_KEY))
283 { 313 {
284 result.ownPrivateKeyPath_ = SerializationToolbox::ReadString(serialized, OWN_PRIVATE_KEY); 314 result.ownPrivateKeyPath_ = SerializationToolbox::ReadString(serialized, OWN_PRIVATE_KEY);
285 } 315 }
286 else 316 else
392 { 422 {
393 boost::mutex::scoped_lock lock(defaultConfigurationMutex_); 423 boost::mutex::scoped_lock lock(defaultConfigurationMutex_);
394 defaultTrustedCertificatesPath_.clear(); 424 defaultTrustedCertificatesPath_.clear();
395 } 425 }
396 } 426 }
427
428
429
430 void DicomAssociationParameters::CheckMaximumPduLength(unsigned int pdu)
431 {
432 if (pdu > ASC_MAXIMUMPDUSIZE)
433 {
434 throw OrthancException(ErrorCode_ParameterOutOfRange, "Maximum PDU length must be smaller than " +
435 boost::lexical_cast<std::string>(ASC_MAXIMUMPDUSIZE));
436 }
437 else if (pdu < ASC_MINIMUMPDUSIZE)
438 {
439 throw OrthancException(ErrorCode_ParameterOutOfRange, "Maximum PDU length must be greater than " +
440 boost::lexical_cast<std::string>(ASC_MINIMUMPDUSIZE));
441 }
442 }
443
444
445 void DicomAssociationParameters::SetDefaultMaximumPduLength(unsigned int pdu)
446 {
447 CheckMaximumPduLength(pdu);
448
449 {
450 boost::mutex::scoped_lock lock(defaultConfigurationMutex_);
451 defaultMaximumPduLength_ = pdu;
452 }
453 }
454
455
456 unsigned int DicomAssociationParameters::GetDefaultMaximumPduLength()
457 {
458 boost::mutex::scoped_lock lock(defaultConfigurationMutex_);
459 return defaultMaximumPduLength_;
460 }
397 } 461 }