< Summary

Information
Class: Ice.Internal.UdpTransceiver
Assembly: Ice
File(s): /_/csharp/src/Ice/Internal/UdpTransceiver.cs
Tag: 91_21789722663
Line coverage
56%
Covered lines: 197
Uncovered lines: 150
Coverable lines: 347
Total lines: 839
Line coverage: 56.7%
Branch coverage
38%
Covered branches: 67
Total branches: 173
Branch coverage: 38.7%
Method coverage
82%
Covered methods: 19
Total methods: 23
Method coverage: 82.6%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
fd()100%210%
initialize(...)50%11.46646.67%
closing(...)100%210%
close()100%2.09271.43%
bind()50%9.21873.33%
destroy()100%11100%
write(...)33.33%46.151238.1%
read(...)5.56%288.14185.88%
startRead(...)33.33%7.13668.42%
finishRead(...)35.71%45.821445.45%
startWrite(...)0%156120%
finishWrite(...)0%272160%
protocol()100%11100%
getInfo(...)68.75%16.011696.55%
checkSendSize(...)100%22100%
setBufferSize(...)100%11100%
ToString()83.33%12.671283.33%
toDetailedString()100%44100%
effectivePort()100%11100%
.ctor(...)83.33%6696.77%
.ctor(...)0%4.08482.76%
setBufSize(...)42.86%47.022871.05%
ioCompleted(...)28.57%13.13750%

File(s)

/_/csharp/src/Ice/Internal/UdpTransceiver.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using System.Diagnostics;
 4using System.Net;
 5using System.Net.Sockets;
 6using System.Text;
 7
 8namespace Ice.Internal;
 9
 10#pragma warning disable CA1001 // _readEventArgs and _writeEventArgs are disposed by destroy.
 11internal sealed class UdpTransceiver : Transceiver
 12#pragma warning restore CA1001
 13{
 014    public Socket fd() => _fd;
 15
 16    public int initialize(Buffer readBuffer, Buffer writeBuffer, ref bool hasMoreData)
 17    {
 118        if (_state == StateNeedConnect)
 19        {
 120            _state = StateConnectPending;
 21            try
 22            {
 123                if (_sourceAddr != null)
 24                {
 025                    _fd.Bind(_sourceAddr);
 26                }
 127                _fd.Connect(_addr);
 128            }
 029            catch (System.Net.Sockets.SocketException ex)
 30            {
 031                if (Network.wouldBlock(ex))
 32                {
 033                    return SocketOperation.Connect;
 34                }
 035                throw new Ice.ConnectFailedException(_addr, ex);
 36            }
 037            catch (System.Exception ex)
 38            {
 039                throw new Ice.ConnectFailedException(_addr, ex);
 40            }
 141            _state = StateConnected;
 42        }
 43
 44        Debug.Assert(_state >= StateConnected);
 145        return SocketOperation.None;
 046    }
 47
 48    public int closing(bool initiator, Ice.LocalException ex) =>
 49        //
 50        // Nothing to do.
 51        //
 052        SocketOperation.None;
 53
 54    public void close()
 55    {
 156        if (_fd != null)
 57        {
 58            try
 59            {
 160                _fd.Close();
 161            }
 062            catch (System.IO.IOException)
 63            {
 064            }
 165            _fd = null;
 66        }
 167    }
 68
 69    public EndpointI bind()
 70    {
 171        if (Network.isMulticast((IPEndPoint)_addr))
 72        {
 173            Network.setReuseAddress(_fd, true);
 174            _mcastAddr = (IPEndPoint)_addr;
 175            if (AssemblyUtil.isWindows)
 76            {
 77                // Windows does not allow binding to the mcast address itself so we bind to INADDR_ANY instead.
 078                _addr = new IPEndPoint(
 079                    _addr.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any,
 080                    _port);
 81            }
 82
 183            _addr = Network.doBind(_fd, _addr);
 184            if (_port == 0)
 85            {
 086                _mcastAddr.Port = ((IPEndPoint)_addr).Port;
 87            }
 188            Network.setMcastGroup(_fd, _mcastAddr.Address, _mcastInterface);
 89        }
 90        else
 91        {
 192            _addr = Network.doBind(_fd, _addr);
 93        }
 194        _bound = true;
 195        _endpoint = _endpoint.endpoint(this);
 196        return _endpoint;
 97    }
 98
 99    public void destroy()
 100    {
 1101        _readEventArgs.Dispose();
 1102        _writeEventArgs.Dispose();
 1103    }
 104
 105    public int write(Buffer buf)
 106    {
 1107        if (!buf.b.hasRemaining())
 108        {
 0109            return SocketOperation.None;
 110        }
 111
 112        Debug.Assert(buf.b.position() == 0);
 113        Debug.Assert(_fd != null && _state >= StateConnected);
 114
 115        // The caller is supposed to check the send size before by calling checkSendSize
 116        Debug.Assert(Math.Min(_maxPacketSize, _sndSize - _udpOverhead) >= buf.size());
 117
 118        int ret;
 119        while (true)
 120        {
 121            try
 122            {
 1123                if (_state == StateConnected)
 124                {
 1125                    ret = _fd.Send(buf.b.rawBytes(), 0, buf.size(), SocketFlags.None);
 126                }
 127                else
 128                {
 1129                    if (_peerAddr == null)
 130                    {
 0131                        throw new Ice.SocketException();
 132                    }
 1133                    ret = _fd.SendTo(buf.b.rawBytes(), 0, buf.size(), SocketFlags.None, _peerAddr);
 134                }
 1135                break;
 136            }
 0137            catch (System.Net.Sockets.SocketException ex)
 138            {
 0139                if (Network.interrupted(ex))
 140                {
 0141                    continue;
 142                }
 143
 0144                if (Network.wouldBlock(ex))
 145                {
 0146                    return SocketOperation.Write;
 147                }
 148
 0149                if (Network.connectionLost(ex))
 150                {
 0151                    throw new Ice.ConnectionLostException(_addr, ex);
 152                }
 153                else
 154                {
 0155                    throw new Ice.SocketException(ex);
 156                }
 157            }
 0158            catch (System.Exception e)
 159            {
 0160                throw new Ice.SyscallException(e);
 161            }
 162        }
 163
 164        Debug.Assert(ret > 0);
 165        Debug.Assert(ret == buf.b.limit());
 1166        buf.b.position(buf.b.limit());
 1167        return SocketOperation.None;
 0168    }
 169
 170    public int read(Buffer buf, ref bool hasMoreData)
 171    {
 1172        if (!buf.b.hasRemaining())
 173        {
 1174            return SocketOperation.None;
 175        }
 176
 177        Debug.Assert(buf.b.position() == 0);
 178        Debug.Assert(_fd != null);
 179
 0180        int packetSize = Math.Min(_maxPacketSize, _rcvSize - _udpOverhead);
 0181        buf.resize(packetSize, true);
 0182        buf.b.position(0);
 183
 184        int ret;
 185        while (true)
 186        {
 187            try
 188            {
 0189                EndPoint peerAddr = _peerAddr;
 0190                if (peerAddr == null)
 191                {
 0192                    if (_addr.AddressFamily == AddressFamily.InterNetwork)
 193                    {
 0194                        peerAddr = new IPEndPoint(IPAddress.Any, 0);
 195                    }
 196                    else
 197                    {
 198                        Debug.Assert(_addr.AddressFamily == AddressFamily.InterNetworkV6);
 0199                        peerAddr = new IPEndPoint(IPAddress.IPv6Any, 0);
 200                    }
 201                }
 202
 0203                if (_state == StateConnected)
 204                {
 0205                    ret = _fd.Receive(buf.b.rawBytes(), 0, buf.b.limit(), SocketFlags.None);
 206                }
 207                else
 208                {
 0209                    ret = _fd.ReceiveFrom(buf.b.rawBytes(), 0, buf.b.limit(), SocketFlags.None, ref peerAddr);
 0210                    _peerAddr = (IPEndPoint)peerAddr;
 211                }
 0212                break;
 213            }
 0214            catch (System.Net.Sockets.SocketException e)
 215            {
 0216                if (Network.recvTruncated(e))
 217                {
 218                    // The message was truncated and the whole buffer is filled. We ignore
 219                    // this error here, it will be detected at the connection level when
 220                    // the Ice message size is checked against the buffer size.
 0221                    ret = buf.size();
 0222                    break;
 223                }
 224
 0225                if (Network.interrupted(e))
 226                {
 0227                    continue;
 228                }
 229
 0230                if (Network.wouldBlock(e))
 231                {
 0232                    return SocketOperation.Read;
 233                }
 234
 0235                if (Network.connectionLost(e))
 236                {
 0237                    throw new ConnectionLostException(_addr, e);
 238                }
 239                else
 240                {
 0241                    throw new Ice.SocketException(e);
 242                }
 243            }
 0244            catch (System.Exception e)
 245            {
 0246                throw new SyscallException(e);
 247            }
 248        }
 249
 0250        if (ret == 0)
 251        {
 0252            throw new Ice.ConnectionLostException(_addr);
 253        }
 254
 255        Debug.Assert(_state != StateNeedConnect);
 256
 0257        buf.resize(ret, true);
 0258        buf.b.position(ret);
 259
 0260        return SocketOperation.None;
 0261    }
 262
 263    public bool startRead(Buffer buf, AsyncCallback callback, object state)
 264    {
 265        Debug.Assert(buf.b.position() == 0);
 266
 1267        int packetSize = Math.Min(_maxPacketSize, _rcvSize - _udpOverhead);
 1268        buf.resize(packetSize, true);
 1269        buf.b.position(0);
 270
 271        try
 272        {
 1273            if (_state == StateConnected)
 274            {
 1275                _readCallback = callback;
 1276                _readEventArgs.UserToken = state;
 1277                _readEventArgs.SetBuffer(buf.b.rawBytes(), buf.b.position(), packetSize);
 1278                return !_fd.ReceiveAsync(_readEventArgs);
 279            }
 280            else
 281            {
 282                Debug.Assert(_incoming);
 1283                _readCallback = callback;
 1284                _readEventArgs.UserToken = state;
 1285                _readEventArgs.SetBuffer(buf.b.rawBytes(), 0, buf.b.limit());
 1286                return !_fd.ReceiveFromAsync(_readEventArgs);
 287            }
 288        }
 0289        catch (System.Net.Sockets.SocketException ex)
 290        {
 0291            if (Network.recvTruncated(ex))
 292            {
 293                // Nothing todo
 0294                return true;
 295            }
 296            else
 297            {
 0298                if (Network.connectionLost(ex))
 299                {
 0300                    throw new Ice.ConnectionLostException(_addr, ex);
 301                }
 302                else
 303                {
 0304                    throw new Ice.SocketException(ex);
 305                }
 306            }
 307        }
 1308    }
 309
 310    public void finishRead(Buffer buf)
 311    {
 1312        if (_fd == null)
 313        {
 0314            return;
 315        }
 316
 317        int ret;
 318        try
 319        {
 1320            if (_readEventArgs.SocketError != SocketError.Success)
 321            {
 0322                throw new System.Net.Sockets.SocketException((int)_readEventArgs.SocketError);
 323            }
 1324            ret = _readEventArgs.BytesTransferred;
 1325            if (_state != StateConnected)
 326            {
 1327                _peerAddr = _readEventArgs.RemoteEndPoint;
 328            }
 1329        }
 0330        catch (System.Net.Sockets.SocketException ex)
 331        {
 0332            if (Network.recvTruncated(ex))
 333            {
 334                // The message was truncated and the whole buffer is filled. We ignore
 335                // this error here, it will be detected at the connection level when
 336                // the Ice message size is checked against the buffer size.
 0337                ret = buf.size();
 338            }
 339            else
 340            {
 0341                if (Network.connectionLost(ex))
 342                {
 0343                    throw new Ice.ConnectionLostException(_addr, ex);
 344                }
 345
 0346                if (Network.connectionRefused(ex))
 347                {
 0348                    throw new Ice.ConnectionRefusedException(_addr, ex);
 349                }
 350                else
 351                {
 0352                    throw new Ice.SocketException(ex);
 353                }
 354            }
 0355        }
 356
 1357        if (ret == 0)
 358        {
 0359            throw new Ice.ConnectionLostException(_addr);
 360        }
 361
 362        Debug.Assert(_state != StateNeedConnect);
 1363        buf.resize(ret, true);
 1364        buf.b.position(ret);
 1365    }
 366
 367    public bool startWrite(Buffer buf, AsyncCallback callback, object state, out bool messageWritten)
 368    {
 0369        if (!_incoming && _state < StateConnected)
 370        {
 371            Debug.Assert(_addr != null);
 0372            messageWritten = false;
 0373            if (_sourceAddr != null)
 374            {
 0375                _fd.Bind(_sourceAddr);
 376            }
 0377            _writeEventArgs.UserToken = state;
 0378            return !_fd.ConnectAsync(_writeEventArgs);
 379        }
 380
 381        Debug.Assert(_fd != null);
 382
 383        // The caller is supposed to check the send size before by calling checkSendSize
 384        Debug.Assert(Math.Min(_maxPacketSize, _sndSize - _udpOverhead) >= buf.size());
 385
 386        Debug.Assert(buf.b.position() == 0);
 387
 388        bool completedSynchronously;
 389        try
 390        {
 0391            _writeCallback = callback;
 392
 0393            if (_state == StateConnected)
 394            {
 0395                _writeEventArgs.UserToken = state;
 0396                _writeEventArgs.SetBuffer(buf.b.rawBytes(), 0, buf.b.limit());
 0397                completedSynchronously = !_fd.SendAsync(_writeEventArgs);
 398            }
 399            else
 400            {
 0401                if (_peerAddr == null)
 402                {
 0403                    throw new Ice.SocketException();
 404                }
 0405                _writeEventArgs.RemoteEndPoint = _peerAddr;
 0406                _writeEventArgs.UserToken = state;
 0407                _writeEventArgs.SetBuffer(buf.b.rawBytes(), 0, buf.b.limit());
 0408                completedSynchronously = !_fd.SendToAsync(_writeEventArgs);
 409            }
 0410        }
 0411        catch (System.Net.Sockets.SocketException ex)
 412        {
 0413            if (Network.connectionLost(ex))
 414            {
 0415                throw new Ice.ConnectionLostException(_addr, ex);
 416            }
 417            else
 418            {
 0419                throw new Ice.SocketException(ex);
 420            }
 421        }
 422
 0423        messageWritten = true;
 0424        return completedSynchronously;
 425    }
 426
 427    public void finishWrite(Buffer buf)
 428    {
 0429        if (_fd == null)
 430        {
 0431            buf.b.position(buf.size()); // Assume all the data was sent for at-most-once semantics.
 0432            _writeEventArgs = null;
 0433            return;
 434        }
 435
 0436        if (!_incoming && _state < StateConnected)
 437        {
 0438            if (_writeEventArgs.SocketError != SocketError.Success)
 439            {
 0440                var ex =
 0441                    new System.Net.Sockets.SocketException((int)_writeEventArgs.SocketError);
 0442                if (Network.connectionRefused(ex))
 443                {
 0444                    throw new Ice.ConnectionRefusedException(_addr, ex);
 445                }
 446                else
 447                {
 0448                    throw new Ice.ConnectFailedException(_addr, ex);
 449                }
 450            }
 0451            return;
 452        }
 453
 454        int ret;
 455        try
 456        {
 0457            if (_writeEventArgs.SocketError != SocketError.Success)
 458            {
 0459                throw new System.Net.Sockets.SocketException((int)_writeEventArgs.SocketError);
 460            }
 0461            ret = _writeEventArgs.BytesTransferred;
 0462        }
 0463        catch (System.Net.Sockets.SocketException ex)
 464        {
 0465            if (Network.connectionLost(ex))
 466            {
 0467                throw new Ice.ConnectionLostException(_addr, ex);
 468            }
 469            else
 470            {
 0471                throw new Ice.SocketException(ex);
 472            }
 473        }
 474
 0475        if (ret == 0)
 476        {
 0477            throw new Ice.ConnectionLostException(_addr);
 478        }
 479
 480        Debug.Assert(ret > 0);
 481        Debug.Assert(ret == buf.b.limit());
 0482        buf.b.position(buf.b.position() + ret);
 0483    }
 484
 1485    public string protocol() => _instance.protocol();
 486
 487    public ConnectionInfo getInfo(bool incoming, string adapterName, string connectionId)
 488    {
 1489        if (_fd is null)
 490        {
 0491            return new UDPConnectionInfo(incoming, adapterName, connectionId);
 492        }
 493        else
 494        {
 1495            EndPoint localEndpoint = Network.getLocalAddress(_fd);
 496
 1497            if (_state == StateNotConnected) // a server connection
 498            {
 499                Debug.Assert(incoming);
 500
 501                // Since this info is cached in the Connection object shared by all the clients, we don't store the
 502                // remote address/port of the latest client in this info.
 1503                return new UDPConnectionInfo(
 1504                    incoming,
 1505                    adapterName,
 1506                    connectionId,
 1507                    Network.endpointAddressToString(localEndpoint),
 1508                    Network.endpointPort(localEndpoint),
 1509                    remoteAddress: "",
 1510                    remotePort: -1,
 1511                    _mcastAddr is not null ? Network.endpointAddressToString(_mcastAddr) : "",
 1512                    _mcastAddr is not null ? Network.endpointPort(_mcastAddr) : -1,
 1513                    _rcvSize,
 1514                    _sndSize);
 515            }
 516            else // client connection
 517            {
 518                Debug.Assert(!incoming);
 1519                EndPoint remoteEndpoint = Network.getRemoteAddress(_fd);
 520
 1521                return new UDPConnectionInfo(
 1522                    incoming,
 1523                    adapterName,
 1524                    connectionId,
 1525                    Network.endpointAddressToString(localEndpoint),
 1526                    Network.endpointPort(localEndpoint),
 1527                    remoteEndpoint is not null ? Network.endpointAddressToString(remoteEndpoint) : "",
 1528                    remoteEndpoint is not null ? Network.endpointPort(remoteEndpoint) : -1,
 1529                    _mcastAddr is not null ? Network.endpointAddressToString(_mcastAddr) : "",
 1530                    _mcastAddr is not null ? Network.endpointPort(_mcastAddr) : -1,
 1531                    _rcvSize,
 1532                    _sndSize);
 533            }
 534        }
 535    }
 536
 537    public void checkSendSize(Buffer buf)
 538    {
 539        //
 540        // The maximum packetSize is either the maximum allowable UDP packet size, or
 541        // the UDP send buffer size (which ever is smaller).
 542        //
 1543        int packetSize = Math.Min(_maxPacketSize, _sndSize - _udpOverhead);
 1544        if (packetSize < buf.size())
 545        {
 1546            throw new Ice.DatagramLimitException();
 547        }
 1548    }
 549
 1550    public void setBufferSize(int rcvSize, int sndSize) => setBufSize(rcvSize, sndSize);
 551
 552    public override string ToString()
 553    {
 1554        if (_fd == null)
 555        {
 0556            return "<closed>";
 557        }
 558
 559        string s;
 1560        if (_incoming && !_bound)
 561        {
 1562            s = "local address = " + Network.addrToString(_addr);
 563        }
 1564        else if (_state == StateNotConnected)
 565        {
 1566            s = "local address = " + Network.localAddrToString(Network.getLocalAddress(_fd));
 1567            if (_peerAddr != null)
 568            {
 0569                s += "\nremote address = " + Network.addrToString(_peerAddr);
 570            }
 571        }
 572        else
 573        {
 1574            s = Network.fdToString(_fd);
 575        }
 576
 1577        if (_mcastAddr != null)
 578        {
 1579            s += "\nmulticast address = " + Network.addrToString(_mcastAddr);
 580        }
 1581        return s;
 582    }
 583
 584    public string toDetailedString()
 585    {
 1586        var s = new StringBuilder(ToString());
 1587        if (_mcastAddr is not null)
 588        {
 1589            List<string> intfs = Network.getInterfacesForMulticast(
 1590                _mcastInterface,
 1591                Network.getProtocolSupport(_mcastAddr.Address));
 1592            if (intfs.Count != 0)
 593            {
 1594                s.Append("\nlocal interfaces = ");
 1595                s.Append(string.Join(", ", intfs.ToArray()));
 596            }
 597        }
 1598        return s.ToString();
 599    }
 600
 1601    public int effectivePort() => Network.endpointPort(_addr);
 602
 603    //
 604    // Only for use by UdpConnector.
 605    //
 1606    internal UdpTransceiver(
 1607        ProtocolInstance instance,
 1608        EndPoint addr,
 1609        EndPoint sourceAddr,
 1610        string mcastInterface,
 1611        int mcastTtl)
 612    {
 1613        _instance = instance;
 1614        _addr = addr;
 1615        _sourceAddr = sourceAddr;
 616
 1617        _readEventArgs = new SocketAsyncEventArgs();
 1618        _readEventArgs.RemoteEndPoint = _addr;
 1619        _readEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ioCompleted);
 620
 1621        _writeEventArgs = new SocketAsyncEventArgs();
 1622        _writeEventArgs.RemoteEndPoint = _addr;
 1623        _writeEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ioCompleted);
 624
 1625        _mcastInterface = mcastInterface;
 1626        _state = StateNeedConnect;
 1627        _incoming = false;
 628
 629        try
 630        {
 1631            _fd = Network.createSocket(true, _addr.AddressFamily);
 1632            setBufSize(-1, -1);
 1633            Network.setBlock(_fd, false);
 1634            if (Network.isMulticast((IPEndPoint)_addr))
 635            {
 1636                if (_mcastInterface.Length > 0)
 637                {
 1638                    Network.setMcastInterface(_fd, _mcastInterface, _addr.AddressFamily);
 639                }
 1640                if (mcastTtl != -1)
 641                {
 0642                    Network.setMcastTtl(_fd, mcastTtl, _addr.AddressFamily);
 643                }
 644            }
 1645        }
 1646        catch (Ice.LocalException)
 647        {
 1648            _fd = null;
 1649            throw;
 650        }
 1651    }
 652
 653    //
 654    // Only for use by UdpEndpoint.
 655    //
 1656    internal UdpTransceiver(
 1657        UdpEndpointI endpoint,
 1658        ProtocolInstance instance,
 1659        string host,
 1660        int port,
 1661        string mcastInterface)
 662    {
 1663        _endpoint = endpoint;
 1664        _instance = instance;
 1665        _state = StateNotConnected;
 1666        _mcastInterface = mcastInterface;
 1667        _incoming = true;
 1668        _port = port;
 669
 670        try
 671        {
 1672            _addr = Network.getAddressForServer(host, port, instance.protocolSupport(), instance.preferIPv6());
 673
 1674            _readEventArgs = new SocketAsyncEventArgs();
 1675            _readEventArgs.RemoteEndPoint = _addr;
 1676            _readEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ioCompleted);
 677
 1678            _writeEventArgs = new SocketAsyncEventArgs();
 1679            _writeEventArgs.RemoteEndPoint = _addr;
 1680            _writeEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ioCompleted);
 681
 1682            _fd = Network.createServerSocket(true, _addr.AddressFamily, instance.protocolSupport());
 1683            setBufSize(-1, -1);
 1684            Network.setBlock(_fd, false);
 1685        }
 0686        catch (Ice.LocalException)
 687        {
 0688            _readEventArgs?.Dispose();
 0689            _writeEventArgs?.Dispose();
 0690            _fd = null;
 0691            throw;
 692        }
 1693    }
 694
 695    private void setBufSize(int rcvSize, int sndSize)
 696    {
 697        Debug.Assert(_fd != null);
 698
 1699        for (int i = 0; i < 2; ++i)
 700        {
 701            bool isSnd;
 702            string direction;
 703            string prop;
 704            int dfltSize;
 705            int sizeRequested;
 1706            if (i == 0)
 707            {
 1708                isSnd = false;
 1709                direction = "receive";
 1710                prop = "Ice.UDP.RcvSize";
 1711                dfltSize = Network.getRecvBufferSize(_fd);
 1712                sizeRequested = rcvSize;
 1713                _rcvSize = dfltSize;
 714            }
 715            else
 716            {
 1717                isSnd = true;
 1718                direction = "send";
 1719                prop = "Ice.UDP.SndSize";
 1720                dfltSize = Network.getSendBufferSize(_fd);
 1721                sizeRequested = sndSize;
 1722                _sndSize = dfltSize;
 723            }
 724
 725            //
 726            // Get property for buffer size if size not passed in.
 727            //
 1728            if (sizeRequested == -1)
 729            {
 1730                sizeRequested = _instance.properties().getPropertyAsIntWithDefault(prop, dfltSize);
 731            }
 732            //
 733            // Check for sanity.
 734            //
 1735            if (sizeRequested < (_udpOverhead + Protocol.headerSize))
 736            {
 0737                _instance.logger().warning("Invalid " + prop + " value of " + sizeRequested + " adjusted to " +
 0738                                           dfltSize);
 0739                sizeRequested = dfltSize;
 740            }
 741
 1742            if (sizeRequested != dfltSize)
 743            {
 744                //
 745                // Try to set the buffer size. The kernel will silently adjust
 746                // the size to an acceptable value. Then read the size back to
 747                // get the size that was actually set.
 748                //
 749                int sizeSet;
 1750                if (i == 0)
 751                {
 1752                    Network.setRecvBufferSize(_fd, sizeRequested);
 1753                    _rcvSize = Network.getRecvBufferSize(_fd);
 1754                    sizeSet = _rcvSize;
 755                }
 756                else
 757                {
 1758                    Network.setSendBufferSize(_fd, sizeRequested);
 1759                    _sndSize = Network.getSendBufferSize(_fd);
 1760                    sizeSet = _sndSize;
 761                }
 762
 763                //
 764                // Warn if the size that was set is less than the requested size
 765                // and we have not already warned
 766                //
 1767                if (sizeSet < sizeRequested)
 768                {
 0769                    BufSizeWarnInfo winfo = _instance.getBufSizeWarn(Ice.UDPEndpointType.value);
 0770                    if ((isSnd && (!winfo.sndWarn || winfo.sndSize != sizeRequested)) ||
 0771                       (!isSnd && (!winfo.rcvWarn || winfo.rcvSize != sizeRequested)))
 772                    {
 0773                        _instance.logger().warning("UDP " + direction + " buffer size: requested size of " +
 0774                                                   sizeRequested + " adjusted to " + sizeSet);
 775
 0776                        if (isSnd)
 777                        {
 0778                            _instance.setSndBufSizeWarn(Ice.UDPEndpointType.value, sizeRequested);
 779                        }
 780                        else
 781                        {
 0782                            _instance.setRcvBufSizeWarn(Ice.UDPEndpointType.value, sizeRequested);
 783                        }
 784                    }
 785                }
 786            }
 787        }
 1788    }
 789
 790    internal void ioCompleted(object sender, SocketAsyncEventArgs e)
 791    {
 1792        switch (e.LastOperation)
 793        {
 794            case SocketAsyncOperation.Receive:
 795            case SocketAsyncOperation.ReceiveFrom:
 1796                _readCallback(e.UserToken);
 1797                break;
 798            case SocketAsyncOperation.Send:
 799            case SocketAsyncOperation.Connect:
 0800                _writeCallback(e.UserToken);
 0801                break;
 802            default:
 0803                throw new ArgumentException("The last operation completed on the socket was not a receive or send");
 804        }
 805    }
 806
 807    private UdpEndpointI _endpoint;
 808    private readonly ProtocolInstance _instance;
 809    private int _state;
 810    private readonly bool _incoming;
 811    private int _rcvSize;
 812    private int _sndSize;
 813    private Socket _fd;
 814    private EndPoint _addr;
 815    private readonly EndPoint _sourceAddr;
 816    private IPEndPoint _mcastAddr;
 817    private EndPoint _peerAddr;
 818    private readonly string _mcastInterface;
 819
 820    private readonly int _port;
 821    private bool _bound;
 822
 823    private SocketAsyncEventArgs _writeEventArgs;
 824    private readonly SocketAsyncEventArgs _readEventArgs;
 825    private AsyncCallback _writeCallback;
 826    private AsyncCallback _readCallback;
 827
 828    private const int StateNeedConnect = 0;
 829    private const int StateConnectPending = 1;
 830    private const int StateConnected = 2;
 831    private const int StateNotConnected = 3;
 832
 833    //
 834    // The maximum IP datagram size is 65535. Subtract 20 bytes for the IP header and 8 bytes for the UDP header
 835    // to get the maximum payload.
 836    //
 837    private const int _udpOverhead = 20 + 8;
 838    private const int _maxPacketSize = 65535 - _udpOverhead;
 839}