1 // 2 // Copyright (c) ZeroC, Inc. All rights reserved. 3 // 4 5 namespace IceInternal 6 { 7 using System.Diagnostics; 8 using System.Collections; 9 using System.Collections.Generic; 10 using System.Net; 11 using System; 12 using System.Globalization; 13 14 sealed class UdpEndpointI : IPEndpointI 15 { UdpEndpointI(ProtocolInstance instance, string ho, int po, EndPoint sourceAddr, string mcastInterface, int mttl, bool conn, string conId, bool co)16 public UdpEndpointI(ProtocolInstance instance, string ho, int po, EndPoint sourceAddr, string mcastInterface, 17 int mttl, bool conn, string conId, bool co) : 18 base(instance, ho, po, sourceAddr, conId) 19 { 20 _mcastInterface = mcastInterface; 21 _mcastTtl = mttl; 22 _connect = conn; 23 _compress = co; 24 } 25 UdpEndpointI(ProtocolInstance instance)26 public UdpEndpointI(ProtocolInstance instance) : 27 base(instance) 28 { 29 _connect = false; 30 _compress = false; 31 } 32 UdpEndpointI(ProtocolInstance instance, Ice.InputStream s)33 public UdpEndpointI(ProtocolInstance instance, Ice.InputStream s) : 34 base(instance, s) 35 { 36 if(s.getEncoding().Equals(Ice.Util.Encoding_1_0)) 37 { 38 s.readByte(); 39 s.readByte(); 40 s.readByte(); 41 s.readByte(); 42 } 43 // Not transmitted. 44 //_connect = s.readBool(); 45 _connect = false; 46 _compress = s.readBool(); 47 } 48 49 private sealed class InfoI : Ice.UDPEndpointInfo 50 { InfoI(UdpEndpointI e)51 public InfoI(UdpEndpointI e) 52 { 53 _endpoint = e; 54 } 55 type()56 override public short type() 57 { 58 return _endpoint.type(); 59 } 60 datagram()61 override public bool datagram() 62 { 63 return _endpoint.datagram(); 64 } 65 secure()66 override public bool secure() 67 { 68 return _endpoint.secure(); 69 } 70 71 private UdpEndpointI _endpoint; 72 } 73 74 // 75 // Return the endpoint information. 76 // getInfo()77 public override Ice.EndpointInfo getInfo() 78 { 79 InfoI info = new InfoI(this); 80 fillEndpointInfo(info); 81 return info; 82 } 83 84 // 85 // Return the timeout for the endpoint in milliseconds. 0 means 86 // non-blocking, -1 means no timeout. 87 // timeout()88 public override int timeout() 89 { 90 return -1; 91 } 92 93 // 94 // Return a new endpoint with a different timeout value, provided 95 // that timeouts are supported by the endpoint. Otherwise the same 96 // endpoint is returned. 97 // timeout(int timeout)98 public override EndpointI timeout(int timeout) 99 { 100 return this; 101 } 102 103 // 104 // Return true if the endpoints support bzip2 compress, or false 105 // otherwise. 106 // compress()107 public override bool compress() 108 { 109 return _compress; 110 } 111 112 // 113 // Return a new endpoint with a different compression value, 114 // provided that compression is supported by the 115 // endpoint. Otherwise the same endpoint is returned. 116 // compress(bool compress)117 public override EndpointI compress(bool compress) 118 { 119 if(compress == _compress) 120 { 121 return this; 122 } 123 else 124 { 125 return new UdpEndpointI(instance_, host_, port_, sourceAddr_, _mcastInterface, _mcastTtl, _connect, 126 connectionId_, compress); 127 } 128 } 129 130 // 131 // Return true if the endpoint is datagram-based. 132 // datagram()133 public override bool datagram() 134 { 135 return true; 136 } 137 138 // 139 // Return a server side transceiver for this endpoint, or null if a 140 // transceiver can only be created by an acceptor. 141 // transceiver()142 public override Transceiver transceiver() 143 { 144 return new UdpTransceiver(this, instance_, host_, port_, _mcastInterface, _connect); 145 } 146 147 // 148 // Return an acceptor for this endpoint, or null if no acceptors 149 // is available. 150 // acceptor(string adapterName)151 public override Acceptor acceptor(string adapterName) 152 { 153 return null; 154 } 155 initWithOptions(List<string> args, bool oaEndpoint)156 public override void initWithOptions(List<string> args, bool oaEndpoint) 157 { 158 base.initWithOptions(args, oaEndpoint); 159 160 if(_mcastInterface.Equals("*")) 161 { 162 if(oaEndpoint) 163 { 164 _mcastInterface = ""; 165 } 166 else 167 { 168 throw new Ice.EndpointParseException("`--interface *' not valid for proxy endpoint `" + 169 ToString() + "'"); 170 } 171 } 172 } 173 endpoint(UdpTransceiver transceiver)174 public UdpEndpointI endpoint(UdpTransceiver transceiver) 175 { 176 int port = transceiver.effectivePort(); 177 if(port == port_) 178 { 179 return this; 180 } 181 else 182 { 183 return new UdpEndpointI(instance_, host_, port, sourceAddr_, _mcastInterface, _mcastTtl, _connect, 184 connectionId_, _compress); 185 } 186 } 187 options()188 public override string options() 189 { 190 // 191 // WARNING: Certain features, such as proxy validation in Glacier2, 192 // depend on the format of proxy strings. Changes to toString() and 193 // methods called to generate parts of the reference string could break 194 // these features. Please review for all features that depend on the 195 // format of proxyToString() before changing this and related code. 196 // 197 string s = base.options(); 198 199 if(_mcastInterface.Length != 0) 200 { 201 s += " --interface " + _mcastInterface; 202 } 203 204 if(_mcastTtl != -1) 205 { 206 s += " --ttl " + _mcastTtl; 207 } 208 209 if(_connect) 210 { 211 s += " -c"; 212 } 213 214 if(_compress) 215 { 216 s += " -z"; 217 } 218 219 return s; 220 } 221 222 // 223 // Compare endpoints for sorting purposes 224 // CompareTo(EndpointI obj)225 public override int CompareTo(EndpointI obj) 226 { 227 if(!(obj is UdpEndpointI)) 228 { 229 return type() < obj.type() ? -1 : 1; 230 } 231 232 UdpEndpointI p = (UdpEndpointI)obj; 233 if(this == p) 234 { 235 return 0; 236 } 237 238 if(!_connect && p._connect) 239 { 240 return -1; 241 } 242 else if(!p._connect && _connect) 243 { 244 return 1; 245 } 246 247 if(!_compress && p._compress) 248 { 249 return -1; 250 } 251 else if(!p._compress && _compress) 252 { 253 return 1; 254 } 255 256 int rc = string.Compare(_mcastInterface, p._mcastInterface, StringComparison.Ordinal); 257 if(rc != 0) 258 { 259 return rc; 260 } 261 262 if(_mcastTtl < p._mcastTtl) 263 { 264 return -1; 265 } 266 else if(p._mcastTtl < _mcastTtl) 267 { 268 return 1; 269 } 270 271 return base.CompareTo(p); 272 } 273 274 // 275 // Marshal the endpoint 276 // streamWriteImpl(Ice.OutputStream s)277 public override void streamWriteImpl(Ice.OutputStream s) 278 { 279 base.streamWriteImpl(s); 280 if(s.getEncoding().Equals(Ice.Util.Encoding_1_0)) 281 { 282 Ice.Util.Protocol_1_0.ice_writeMembers(s); 283 Ice.Util.Encoding_1_0.ice_writeMembers(s); 284 } 285 // Not transmitted. 286 //s.writeBool(_connect); 287 s.writeBool(_compress); 288 } 289 hashInit(ref int h)290 public override void hashInit(ref int h) 291 { 292 base.hashInit(ref h); 293 HashUtil.hashAdd(ref h, _mcastInterface); 294 HashUtil.hashAdd(ref h, _mcastTtl); 295 HashUtil.hashAdd(ref h, _connect); 296 HashUtil.hashAdd(ref h, _compress); 297 } 298 fillEndpointInfo(Ice.IPEndpointInfo info)299 public override void fillEndpointInfo(Ice.IPEndpointInfo info) 300 { 301 base.fillEndpointInfo(info); 302 if(info is Ice.UDPEndpointInfo) 303 { 304 Ice.UDPEndpointInfo udpInfo = (Ice.UDPEndpointInfo)info; 305 udpInfo.timeout = -1; 306 udpInfo.compress = _compress; 307 udpInfo.mcastInterface = _mcastInterface; 308 udpInfo.mcastTtl = _mcastTtl; 309 } 310 } 311 checkOption(string option, string argument, string endpoint)312 protected override bool checkOption(string option, string argument, string endpoint) 313 { 314 if(base.checkOption(option, argument, endpoint)) 315 { 316 return true; 317 } 318 319 if(option.Equals("-c")) 320 { 321 if(argument != null) 322 { 323 Ice.EndpointParseException e = new Ice.EndpointParseException(); 324 e.str = "unexpected argument `" + argument + "' provided for -c option in " + endpoint; 325 throw e; 326 } 327 328 _connect = true; 329 } 330 else if(option.Equals("-z")) 331 { 332 if(argument != null) 333 { 334 Ice.EndpointParseException e = new Ice.EndpointParseException(); 335 e.str = "unexpected argument `" + argument + "' provided for -z option in " + endpoint; 336 throw e; 337 } 338 339 _compress = true; 340 } 341 else if(option.Equals("-v") || option.Equals("-e")) 342 { 343 if(argument == null) 344 { 345 Ice.EndpointParseException e = new Ice.EndpointParseException(); 346 e.str = "no argument provided for " + option + " option in endpoint " + endpoint; 347 throw e; 348 } 349 350 try 351 { 352 Ice.EncodingVersion v = Ice.Util.stringToEncodingVersion(argument); 353 if(v.major != 1 || v.minor != 0) 354 { 355 instance_.logger().warning("deprecated udp endpoint option: " + option); 356 } 357 } 358 catch(Ice.VersionParseException ex) 359 { 360 Ice.EndpointParseException e = new Ice.EndpointParseException(); 361 e.str = "invalid version `" + argument + "' in endpoint " + endpoint + ":\n" + ex.str; 362 throw e; 363 } 364 } 365 else if(option.Equals("--ttl")) 366 { 367 if(argument == null) 368 { 369 Ice.EndpointParseException e = new Ice.EndpointParseException(); 370 e.str = "no argument provided for --ttl option in endpoint " + endpoint; 371 throw e; 372 } 373 374 try 375 { 376 _mcastTtl = int.Parse(argument, CultureInfo.InvariantCulture); 377 } 378 catch(FormatException ex) 379 { 380 Ice.EndpointParseException e = new Ice.EndpointParseException(ex); 381 e.str = "invalid TTL value `" + argument + "' in endpoint " + endpoint; 382 throw e; 383 } 384 385 if(_mcastTtl < 0) 386 { 387 Ice.EndpointParseException e = new Ice.EndpointParseException(); 388 e.str = "TTL value `" + argument + "' out of range in endpoint " + endpoint; 389 throw e; 390 } 391 } 392 else if(option.Equals("--interface")) 393 { 394 if(argument == null) 395 { 396 Ice.EndpointParseException e = new Ice.EndpointParseException(); 397 e.str = "no argument provided for --interface option in endpoint " + endpoint; 398 throw e; 399 } 400 _mcastInterface = argument; 401 } 402 else 403 { 404 return false; 405 } 406 407 return true; 408 } 409 createConnector(EndPoint addr, NetworkProxy proxy)410 protected override Connector createConnector(EndPoint addr, NetworkProxy proxy) 411 { 412 return new UdpConnector(instance_, addr, sourceAddr_, _mcastInterface, _mcastTtl, connectionId_); 413 } 414 createEndpoint(string host, int port, string connectionId)415 protected override IPEndpointI createEndpoint(string host, int port, string connectionId) 416 { 417 return new UdpEndpointI(instance_, host, port, sourceAddr_, _mcastInterface, _mcastTtl, _connect, 418 connectionId, _compress); 419 } 420 421 private string _mcastInterface = ""; 422 private int _mcastTtl = -1; 423 private bool _connect; 424 private bool _compress; 425 } 426 427 sealed class UdpEndpointFactory : EndpointFactory 428 { UdpEndpointFactory(ProtocolInstance instance)429 internal UdpEndpointFactory(ProtocolInstance instance) 430 { 431 _instance = instance; 432 } 433 initialize()434 public void initialize() 435 { 436 } 437 type()438 public short type() 439 { 440 return _instance.type(); 441 } 442 protocol()443 public string protocol() 444 { 445 return _instance.protocol(); 446 } 447 create(List<string> args, bool oaEndpoint)448 public EndpointI create(List<string> args, bool oaEndpoint) 449 { 450 IPEndpointI endpt = new UdpEndpointI(_instance); 451 endpt.initWithOptions(args, oaEndpoint); 452 return endpt; 453 } 454 read(Ice.InputStream s)455 public EndpointI read(Ice.InputStream s) 456 { 457 return new UdpEndpointI(_instance, s); 458 } 459 destroy()460 public void destroy() 461 { 462 _instance = null; 463 } 464 clone(ProtocolInstance instance)465 public EndpointFactory clone(ProtocolInstance instance) 466 { 467 return new UdpEndpointFactory(instance); 468 } 469 470 private ProtocolInstance _instance; 471 } 472 473 } 474