1 // 2 // Copyright (c) ZeroC, Inc. All rights reserved. 3 // 4 5 namespace IceInternal 6 { 7 using System; 8 using System.Collections.Generic; 9 using System.ComponentModel; 10 using System.Diagnostics; 11 using System.Net; 12 using System.Net.Sockets; 13 using System.Text; 14 15 sealed class UdpTransceiver : Transceiver 16 { fd()17 public Socket fd() 18 { 19 return _fd; 20 } 21 initialize(Buffer readBuffer, Buffer writeBuffer, ref bool hasMoreData)22 public int initialize(Buffer readBuffer, Buffer writeBuffer, ref bool hasMoreData) 23 { 24 if(_state == StateNeedConnect) 25 { 26 _state = StateConnectPending; 27 try 28 { 29 if(_sourceAddr != null) 30 { 31 _fd.Bind(_sourceAddr); 32 } 33 _fd.Connect(_addr); 34 } 35 catch(SocketException ex) 36 { 37 if(Network.wouldBlock(ex)) 38 { 39 return SocketOperation.Connect; 40 } 41 throw new Ice.ConnectFailedException(ex); 42 } 43 catch(Exception ex) 44 { 45 throw new Ice.ConnectFailedException(ex); 46 } 47 _state = StateConnected; 48 } 49 50 Debug.Assert(_state >= StateConnected); 51 return SocketOperation.None; 52 } 53 closing(bool initiator, Ice.LocalException ex)54 public int closing(bool initiator, Ice.LocalException ex) 55 { 56 // 57 // Nothing to do. 58 // 59 return SocketOperation.None; 60 } 61 close()62 public void close() 63 { 64 if(_fd != null) 65 { 66 try 67 { 68 _fd.Close(); 69 } 70 catch(System.IO.IOException) 71 { 72 } 73 _fd = null; 74 } 75 } 76 bind()77 public EndpointI bind() 78 { 79 if(Network.isMulticast((IPEndPoint)_addr)) 80 { 81 Network.setReuseAddress(_fd, true); 82 _mcastAddr = (IPEndPoint)_addr; 83 if(AssemblyUtil.isWindows) 84 { 85 // 86 // Windows does not allow binding to the mcast address itself 87 // so we bind to INADDR_ANY (0.0.0.0) instead. As a result, 88 // bi-directional connection won't work because the source 89 // address won't the multicast address and the client will 90 // therefore reject the datagram. 91 // 92 if(_addr.AddressFamily == AddressFamily.InterNetwork) 93 { 94 _addr = new IPEndPoint(IPAddress.Any, _port); 95 } 96 else 97 { 98 _addr = new IPEndPoint(IPAddress.IPv6Any, _port); 99 } 100 } 101 102 _addr = Network.doBind(_fd, _addr); 103 if(_port == 0) 104 { 105 _mcastAddr.Port = ((IPEndPoint)_addr).Port; 106 } 107 Network.setMcastGroup(_fd, _mcastAddr.Address, _mcastInterface); 108 } 109 else 110 { 111 _addr = Network.doBind(_fd, _addr); 112 } 113 _bound = true; 114 _endpoint = _endpoint.endpoint(this); 115 return _endpoint; 116 } 117 destroy()118 public void destroy() 119 { 120 _readEventArgs.Dispose(); 121 _writeEventArgs.Dispose(); 122 } 123 write(Buffer buf)124 public int write(Buffer buf) 125 { 126 if(!buf.b.hasRemaining()) 127 { 128 return SocketOperation.None; 129 } 130 131 Debug.Assert(buf.b.position() == 0); 132 Debug.Assert(_fd != null && _state >= StateConnected); 133 134 // The caller is supposed to check the send size before by calling checkSendSize 135 Debug.Assert(Math.Min(_maxPacketSize, _sndSize - _udpOverhead) >= buf.size()); 136 137 int ret = 0; 138 while(true) 139 { 140 try 141 { 142 if(_state == StateConnected) 143 { 144 ret = _fd.Send(buf.b.rawBytes(), 0, buf.size(), SocketFlags.None); 145 } 146 else 147 { 148 if(_peerAddr == null) 149 { 150 throw new Ice.SocketException(); 151 } 152 ret = _fd.SendTo(buf.b.rawBytes(), 0, buf.size(), SocketFlags.None, _peerAddr); 153 } 154 break; 155 } 156 catch(SocketException ex) 157 { 158 if(Network.interrupted(ex)) 159 { 160 continue; 161 } 162 163 if(Network.wouldBlock(ex)) 164 { 165 return SocketOperation.Write; 166 } 167 168 if(Network.connectionLost(ex)) 169 { 170 throw new Ice.ConnectionLostException(ex); 171 } 172 else 173 { 174 throw new Ice.SocketException(ex); 175 } 176 } 177 catch(Exception e) 178 { 179 throw new Ice.SyscallException(e); 180 } 181 } 182 183 Debug.Assert(ret > 0); 184 Debug.Assert(ret == buf.b.limit()); 185 buf.b.position(buf.b.limit()); 186 return SocketOperation.None; 187 } 188 read(Buffer buf, ref bool hasMoreData)189 public int read(Buffer buf, ref bool hasMoreData) 190 { 191 if(!buf.b.hasRemaining()) 192 { 193 return SocketOperation.None; 194 } 195 196 Debug.Assert(buf.b.position() == 0); 197 Debug.Assert(_fd != null); 198 199 int packetSize = Math.Min(_maxPacketSize, _rcvSize - _udpOverhead); 200 buf.resize(packetSize, true); 201 buf.b.position(0); 202 203 int ret = 0; 204 while(true) 205 { 206 try 207 { 208 EndPoint peerAddr = _peerAddr; 209 if(peerAddr == null) 210 { 211 if(_addr.AddressFamily == AddressFamily.InterNetwork) 212 { 213 peerAddr = new IPEndPoint(IPAddress.Any, 0); 214 } 215 else 216 { 217 Debug.Assert(_addr.AddressFamily == AddressFamily.InterNetworkV6); 218 peerAddr = new IPEndPoint(IPAddress.IPv6Any, 0); 219 } 220 } 221 222 // TODO: Workaround for https://github.com/dotnet/corefx/issues/31182 223 if(_state == StateConnected || 224 AssemblyUtil.isMacOS && _fd.AddressFamily == AddressFamily.InterNetworkV6 && _fd.DualMode) 225 { 226 ret = _fd.Receive(buf.b.rawBytes(), 0, buf.b.limit(), SocketFlags.None); 227 } 228 else 229 { 230 ret = _fd.ReceiveFrom(buf.b.rawBytes(), 0, buf.b.limit(), SocketFlags.None, ref peerAddr); 231 _peerAddr = (IPEndPoint)peerAddr; 232 } 233 break; 234 } 235 catch(SocketException e) 236 { 237 if(Network.recvTruncated(e)) 238 { 239 // The message was truncated and the whole buffer is filled. We ignore 240 // this error here, it will be detected at the connection level when 241 // the Ice message size is checked against the buffer size. 242 ret = buf.size(); 243 break; 244 } 245 246 if(Network.interrupted(e)) 247 { 248 continue; 249 } 250 251 if(Network.wouldBlock(e)) 252 { 253 return SocketOperation.Read; 254 } 255 256 if(Network.connectionLost(e)) 257 { 258 throw new Ice.ConnectionLostException(); 259 } 260 else 261 { 262 throw new Ice.SocketException(e); 263 } 264 } 265 catch(Exception e) 266 { 267 throw new Ice.SyscallException(e); 268 } 269 } 270 271 if(ret == 0) 272 { 273 throw new Ice.ConnectionLostException(); 274 } 275 276 if(_state == StateNeedConnect) 277 { 278 Debug.Assert(_incoming); 279 280 // 281 // If we must connect, then we connect to the first peer that sends us a packet. 282 // 283 bool connected = Network.doConnect(_fd, _peerAddr, null); 284 Debug.Assert(connected); 285 _state = StateConnected; // We're connected now 286 287 if(_instance.traceLevel() >= 1) 288 { 289 string s = "connected " + protocol() + " socket\n" + ToString(); 290 _instance.logger().trace(_instance.traceCategory(), s); 291 } 292 } 293 294 buf.resize(ret, true); 295 buf.b.position(ret); 296 297 return SocketOperation.None; 298 } 299 startRead(Buffer buf, AsyncCallback callback, object state)300 public bool startRead(Buffer buf, AsyncCallback callback, object state) 301 { 302 Debug.Assert(buf.b.position() == 0); 303 304 int packetSize = Math.Min(_maxPacketSize, _rcvSize - _udpOverhead); 305 buf.resize(packetSize, true); 306 buf.b.position(0); 307 308 try 309 { 310 // TODO: Workaround for https://github.com/dotnet/corefx/issues/31182 311 if(_state == StateConnected || 312 AssemblyUtil.isMacOS && _fd.AddressFamily == AddressFamily.InterNetworkV6 && _fd.DualMode) 313 { 314 _readCallback = callback; 315 _readEventArgs.UserToken = state; 316 _readEventArgs.SetBuffer(buf.b.rawBytes(), buf.b.position(), packetSize); 317 return !_fd.ReceiveAsync(_readEventArgs); 318 } 319 else 320 { 321 Debug.Assert(_incoming); 322 _readCallback = callback; 323 _readEventArgs.UserToken = state; 324 _readEventArgs.SetBuffer(buf.b.rawBytes(), 0, buf.b.limit()); 325 return !_fd.ReceiveFromAsync(_readEventArgs); 326 } 327 } 328 catch(SocketException ex) 329 { 330 if(Network.recvTruncated(ex)) 331 { 332 // Nothing todo 333 return true; 334 } 335 else 336 { 337 if(Network.connectionLost(ex)) 338 { 339 throw new Ice.ConnectionLostException(ex); 340 } 341 else 342 { 343 throw new Ice.SocketException(ex); 344 } 345 } 346 } 347 } 348 finishRead(Buffer buf)349 public void finishRead(Buffer buf) 350 { 351 if(_fd == null) 352 { 353 return; 354 } 355 356 int ret; 357 try 358 { 359 if(_readEventArgs.SocketError != SocketError.Success) 360 { 361 throw new SocketException((int)_readEventArgs.SocketError); 362 } 363 ret = _readEventArgs.BytesTransferred; 364 // TODO: Workaround for https://github.com/dotnet/corefx/issues/31182 365 if(_state != StateConnected && 366 !(AssemblyUtil.isMacOS && _fd.AddressFamily == AddressFamily.InterNetworkV6 && _fd.DualMode)) 367 { 368 _peerAddr = _readEventArgs.RemoteEndPoint; 369 } 370 } 371 catch(SocketException ex) 372 { 373 if(Network.recvTruncated(ex)) 374 { 375 // The message was truncated and the whole buffer is filled. We ignore 376 // this error here, it will be detected at the connection level when 377 // the Ice message size is checked against the buffer size. 378 ret = buf.size(); 379 } 380 else 381 { 382 if(Network.connectionLost(ex)) 383 { 384 throw new Ice.ConnectionLostException(ex); 385 } 386 387 if(Network.connectionRefused(ex)) 388 { 389 throw new Ice.ConnectionRefusedException(ex); 390 } 391 else 392 { 393 throw new Ice.SocketException(ex); 394 } 395 } 396 } 397 398 if(ret == 0) 399 { 400 throw new Ice.ConnectionLostException(); 401 } 402 403 Debug.Assert(ret > 0); 404 405 if(_state == StateNeedConnect) 406 { 407 Debug.Assert(_incoming); 408 409 // 410 // If we must connect, then we connect to the first peer that 411 // sends us a packet. 412 // 413 bool connected = !_fd.ConnectAsync(_readEventArgs); 414 Debug.Assert(connected); 415 _state = StateConnected; // We're connected now 416 417 if(_instance.traceLevel() >= 1) 418 { 419 string s = "connected " + protocol() + " socket\n" + ToString(); 420 _instance.logger().trace(_instance.traceCategory(), s); 421 } 422 } 423 424 buf.resize(ret, true); 425 buf.b.position(ret); 426 } 427 startWrite(Buffer buf, AsyncCallback callback, object state, out bool completed)428 public bool startWrite(Buffer buf, AsyncCallback callback, object state, out bool completed) 429 { 430 if(!_incoming && _state < StateConnected) 431 { 432 Debug.Assert(_addr != null); 433 completed = false; 434 if(_sourceAddr != null) 435 { 436 _fd.Bind(_sourceAddr); 437 } 438 _writeEventArgs.UserToken = state; 439 return !_fd.ConnectAsync(_writeEventArgs); 440 } 441 442 Debug.Assert(_fd != null); 443 444 // The caller is supposed to check the send size before by calling checkSendSize 445 Debug.Assert(Math.Min(_maxPacketSize, _sndSize - _udpOverhead) >= buf.size()); 446 447 Debug.Assert(buf.b.position() == 0); 448 449 bool completedSynchronously; 450 try 451 { 452 _writeCallback = callback; 453 454 if(_state == StateConnected) 455 { 456 _writeEventArgs.UserToken = state; 457 _writeEventArgs.SetBuffer(buf.b.rawBytes(), 0, buf.b.limit()); 458 completedSynchronously = !_fd.SendAsync(_writeEventArgs); 459 } 460 else 461 { 462 if(_peerAddr == null) 463 { 464 throw new Ice.SocketException(); 465 } 466 _writeEventArgs.RemoteEndPoint = _peerAddr; 467 _writeEventArgs.UserToken = state; 468 _writeEventArgs.SetBuffer(buf.b.rawBytes(), 0, buf.b.limit()); 469 completedSynchronously = !_fd.SendToAsync(_writeEventArgs); 470 } 471 } 472 catch(SocketException ex) 473 { 474 if(Network.connectionLost(ex)) 475 { 476 throw new Ice.ConnectionLostException(ex); 477 } 478 else 479 { 480 throw new Ice.SocketException(ex); 481 } 482 } 483 484 completed = true; 485 return completedSynchronously; 486 } 487 finishWrite(Buffer buf)488 public void finishWrite(Buffer buf) 489 { 490 if(_fd == null) 491 { 492 buf.b.position(buf.size()); // Assume all the data was sent for at-most-once semantics. 493 _writeEventArgs = null; 494 return; 495 } 496 497 if(!_incoming && _state < StateConnected) 498 { 499 if(_writeEventArgs.SocketError != SocketError.Success) 500 { 501 SocketException ex = new SocketException((int)_writeEventArgs.SocketError); 502 if(Network.connectionRefused(ex)) 503 { 504 throw new Ice.ConnectionRefusedException(ex); 505 } 506 else 507 { 508 throw new Ice.ConnectFailedException(ex); 509 } 510 } 511 return; 512 } 513 514 int ret; 515 try 516 { 517 if(_writeEventArgs.SocketError != SocketError.Success) 518 { 519 throw new SocketException((int)_writeEventArgs.SocketError); 520 } 521 ret = _writeEventArgs.BytesTransferred; 522 } 523 catch(SocketException ex) 524 { 525 if(Network.connectionLost(ex)) 526 { 527 throw new Ice.ConnectionLostException(ex); 528 } 529 else 530 { 531 throw new Ice.SocketException(ex); 532 } 533 } 534 535 if(ret == 0) 536 { 537 throw new Ice.ConnectionLostException(); 538 } 539 540 Debug.Assert(ret > 0); 541 Debug.Assert(ret == buf.b.limit()); 542 buf.b.position(buf.b.position() + ret); 543 } 544 protocol()545 public string protocol() 546 { 547 return _instance.protocol(); 548 } 549 getInfo()550 public Ice.ConnectionInfo getInfo() 551 { 552 Ice.UDPConnectionInfo info = new Ice.UDPConnectionInfo(); 553 if(_fd != null) 554 { 555 EndPoint localEndpoint = Network.getLocalAddress(_fd); 556 info.localAddress = Network.endpointAddressToString(localEndpoint); 557 info.localPort = Network.endpointPort(localEndpoint); 558 if(_state == StateNotConnected) 559 { 560 if(_peerAddr != null) 561 { 562 info.remoteAddress = Network.endpointAddressToString(_peerAddr); 563 info.remotePort = Network.endpointPort(_peerAddr); 564 } 565 } 566 else 567 { 568 EndPoint remoteEndpoint = Network.getRemoteAddress(_fd); 569 if(remoteEndpoint != null) 570 { 571 info.remoteAddress = Network.endpointAddressToString(remoteEndpoint); 572 info.remotePort = Network.endpointPort(remoteEndpoint); 573 } 574 } 575 info.rcvSize = Network.getRecvBufferSize(_fd); 576 info.sndSize = Network.getSendBufferSize(_fd); 577 } 578 579 if(_mcastAddr != null) 580 { 581 info.mcastAddress = Network.endpointAddressToString(_mcastAddr); 582 info.mcastPort = Network.endpointPort(_mcastAddr); 583 } 584 return info; 585 } 586 checkSendSize(Buffer buf)587 public void checkSendSize(Buffer buf) 588 { 589 // 590 // The maximum packetSize is either the maximum allowable UDP packet size, or 591 // the UDP send buffer size (which ever is smaller). 592 // 593 int packetSize = Math.Min(_maxPacketSize, _sndSize - _udpOverhead); 594 if(packetSize < buf.size()) 595 { 596 throw new Ice.DatagramLimitException(); 597 } 598 } 599 setBufferSize(int rcvSize, int sndSize)600 public void setBufferSize(int rcvSize, int sndSize) 601 { 602 setBufSize(rcvSize, sndSize); 603 } 604 ToString()605 public override string ToString() 606 { 607 if(_fd == null) 608 { 609 return "<closed>"; 610 } 611 612 string s; 613 if(_incoming && !_bound) 614 { 615 s = "local address = " + Network.addrToString(_addr); 616 } 617 else if(_state == StateNotConnected) 618 { 619 s = "local address = " + Network.localAddrToString(Network.getLocalAddress(_fd)); 620 if(_peerAddr != null) 621 { 622 s += "\nremote address = " + Network.addrToString(_peerAddr); 623 } 624 } 625 else 626 { 627 s = Network.fdToString(_fd); 628 } 629 630 if(_mcastAddr != null) 631 { 632 s += "\nmulticast address = " + Network.addrToString(_mcastAddr); 633 } 634 return s; 635 } 636 toDetailedString()637 public string toDetailedString() 638 { 639 StringBuilder s = new StringBuilder(ToString()); 640 List<string> intfs; 641 if(_mcastAddr == null) 642 { 643 intfs = Network.getHostsForEndpointExpand(Network.endpointAddressToString(_addr), 644 _instance.protocolSupport(), true); 645 } 646 else 647 { 648 intfs = Network.getInterfacesForMulticast(_mcastInterface, 649 Network.getProtocolSupport(_mcastAddr.Address)); 650 } 651 if(intfs.Count != 0) 652 { 653 s.Append("\nlocal interfaces = "); 654 s.Append(string.Join(", ", intfs.ToArray())); 655 } 656 return s.ToString(); 657 } 658 effectivePort()659 public int effectivePort() 660 { 661 return Network.endpointPort(_addr); 662 } 663 664 // 665 // Only for use by UdpConnector. 666 // UdpTransceiver(ProtocolInstance instance, EndPoint addr, EndPoint sourceAddr, string mcastInterface, int mcastTtl)667 internal UdpTransceiver(ProtocolInstance instance, EndPoint addr, EndPoint sourceAddr, string mcastInterface, 668 int mcastTtl) 669 { 670 _instance = instance; 671 _addr = addr; 672 _sourceAddr = sourceAddr; 673 674 _readEventArgs = new SocketAsyncEventArgs(); 675 _readEventArgs.RemoteEndPoint = _addr; 676 _readEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ioCompleted); 677 678 _writeEventArgs = new SocketAsyncEventArgs(); 679 _writeEventArgs.RemoteEndPoint = _addr; 680 _writeEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ioCompleted); 681 682 _mcastInterface = mcastInterface; 683 _state = StateNeedConnect; 684 _incoming = false; 685 686 try 687 { 688 _fd = Network.createSocket(true, _addr.AddressFamily); 689 setBufSize(-1, -1); 690 Network.setBlock(_fd, false); 691 if(Network.isMulticast((IPEndPoint)_addr)) 692 { 693 if(_mcastInterface.Length > 0) 694 { 695 Network.setMcastInterface(_fd, _mcastInterface, _addr.AddressFamily); 696 } 697 if(mcastTtl != -1) 698 { 699 Network.setMcastTtl(_fd, mcastTtl, _addr.AddressFamily); 700 } 701 } 702 } 703 catch(Ice.LocalException) 704 { 705 _fd = null; 706 throw; 707 } 708 } 709 710 // 711 // Only for use by UdpEndpoint. 712 // UdpTransceiver(UdpEndpointI endpoint, ProtocolInstance instance, string host, int port, string mcastInterface, bool connect)713 internal UdpTransceiver(UdpEndpointI endpoint, ProtocolInstance instance, string host, int port, 714 string mcastInterface, bool connect) 715 { 716 _endpoint = endpoint; 717 _instance = instance; 718 _state = connect ? StateNeedConnect : StateNotConnected; 719 _mcastInterface = mcastInterface; 720 _incoming = true; 721 _port = port; 722 723 try 724 { 725 _addr = Network.getAddressForServer(host, port, instance.protocolSupport(), instance.preferIPv6()); 726 727 _readEventArgs = new SocketAsyncEventArgs(); 728 _readEventArgs.RemoteEndPoint = _addr; 729 _readEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ioCompleted); 730 731 _writeEventArgs = new SocketAsyncEventArgs(); 732 _writeEventArgs.RemoteEndPoint = _addr; 733 _writeEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ioCompleted); 734 735 _fd = Network.createServerSocket(true, _addr.AddressFamily, instance.protocolSupport()); 736 setBufSize(-1, -1); 737 Network.setBlock(_fd, false); 738 } 739 catch(Ice.LocalException) 740 { 741 if(_readEventArgs != null) 742 { 743 _readEventArgs.Dispose(); 744 } 745 if(_writeEventArgs != null) 746 { 747 _writeEventArgs.Dispose(); 748 } 749 _fd = null; 750 throw; 751 } 752 } 753 setBufSize(int rcvSize, int sndSize)754 private void setBufSize(int rcvSize, int sndSize) 755 { 756 Debug.Assert(_fd != null); 757 758 for (int i = 0; i < 2; ++i) 759 { 760 bool isSnd; 761 string direction; 762 string prop; 763 int dfltSize; 764 int sizeRequested; 765 if(i == 0) 766 { 767 isSnd = false; 768 direction = "receive"; 769 prop = "Ice.UDP.RcvSize"; 770 dfltSize = Network.getRecvBufferSize(_fd); 771 sizeRequested = rcvSize; 772 _rcvSize = dfltSize; 773 } 774 else 775 { 776 isSnd = true; 777 direction = "send"; 778 prop = "Ice.UDP.SndSize"; 779 dfltSize = Network.getSendBufferSize(_fd); 780 sizeRequested = sndSize; 781 _sndSize = dfltSize; 782 } 783 784 // 785 // Get property for buffer size if size not passed in. 786 // 787 if(sizeRequested == -1) 788 { 789 sizeRequested = _instance.properties().getPropertyAsIntWithDefault(prop, dfltSize); 790 } 791 // 792 // Check for sanity. 793 // 794 if(sizeRequested < (_udpOverhead + Protocol.headerSize)) 795 { 796 _instance.logger().warning("Invalid " + prop + " value of " + sizeRequested + " adjusted to " + 797 dfltSize); 798 sizeRequested = dfltSize; 799 } 800 801 if(sizeRequested != dfltSize) 802 { 803 // 804 // Try to set the buffer size. The kernel will silently adjust 805 // the size to an acceptable value. Then read the size back to 806 // get the size that was actually set. 807 // 808 int sizeSet; 809 if(i == 0) 810 { 811 Network.setRecvBufferSize(_fd, sizeRequested); 812 _rcvSize = Network.getRecvBufferSize(_fd); 813 sizeSet = _rcvSize; 814 } 815 else 816 { 817 Network.setSendBufferSize(_fd, sizeRequested); 818 _sndSize = Network.getSendBufferSize(_fd); 819 sizeSet = _sndSize; 820 } 821 822 // 823 // Warn if the size that was set is less than the requested size 824 // and we have not already warned 825 // 826 if(sizeSet < sizeRequested) 827 { 828 BufSizeWarnInfo winfo = _instance.getBufSizeWarn(Ice.UDPEndpointType.value); 829 if((isSnd && (!winfo.sndWarn || winfo.sndSize != sizeRequested)) || 830 (!isSnd && (!winfo.rcvWarn || winfo.rcvSize != sizeRequested))) 831 { 832 _instance.logger().warning("UDP " + direction + " buffer size: requested size of " + 833 sizeRequested + " adjusted to " + sizeSet); 834 835 if(isSnd) 836 { 837 _instance.setSndBufSizeWarn(Ice.UDPEndpointType.value, sizeRequested); 838 } 839 else 840 { 841 _instance.setRcvBufSizeWarn(Ice.UDPEndpointType.value, sizeRequested); 842 } 843 } 844 } 845 } 846 } 847 } 848 ioCompleted(object sender, SocketAsyncEventArgs e)849 internal void ioCompleted(object sender, SocketAsyncEventArgs e) 850 { 851 switch (e.LastOperation) 852 { 853 case SocketAsyncOperation.Receive: 854 case SocketAsyncOperation.ReceiveFrom: 855 _readCallback(e.UserToken); 856 break; 857 case SocketAsyncOperation.Send: 858 case SocketAsyncOperation.Connect: 859 _writeCallback(e.UserToken); 860 break; 861 default: 862 throw new ArgumentException("The last operation completed on the socket was not a receive or send"); 863 } 864 } 865 866 private UdpEndpointI _endpoint; 867 private ProtocolInstance _instance; 868 private int _state; 869 private bool _incoming; 870 private int _rcvSize; 871 private int _sndSize; 872 private Socket _fd; 873 private EndPoint _addr; 874 private EndPoint _sourceAddr; 875 private IPEndPoint _mcastAddr = null; 876 private EndPoint _peerAddr = null; 877 private string _mcastInterface = null; 878 879 private int _port = 0; 880 private bool _bound = false; 881 882 private SocketAsyncEventArgs _writeEventArgs; 883 private SocketAsyncEventArgs _readEventArgs; 884 885 AsyncCallback _writeCallback; 886 AsyncCallback _readCallback; 887 888 private const int StateNeedConnect = 0; 889 private const int StateConnectPending = 1; 890 private const int StateConnected = 2; 891 private const int StateNotConnected = 3; 892 893 // 894 // The maximum IP datagram size is 65535. Subtract 20 bytes for the IP header and 8 bytes for the UDP header 895 // to get the maximum payload. 896 // 897 private const int _udpOverhead = 20 + 8; 898 private const int _maxPacketSize = 65535 - _udpOverhead; 899 } 900 } 901