public int Connect(ref ArraySegment <byte> readBuffer, IList <ArraySegment <byte> > writeBuffer) { if (_state == StateNeedConnect) { _state = StateConnectPending; return(SocketOperation.Connect); } else if (_state <= StateConnectPending) { Debug.Assert(_writeEventArgs != null); if (_writeEventArgs.SocketError != SocketError.Success) { var ex = new SocketException((int)_writeEventArgs.SocketError); if (Network.ConnectionRefused(ex)) { throw new ConnectionRefusedException(ex); } else { throw new ConnectFailedException(ex); } } Debug.Assert(_fd != null); _desc = Network.FdToString(_fd, _proxy, _addr); _state = _proxy != null ? StateProxyWrite : StateConnected; } if (_state == StateProxyWrite) { Debug.Assert(_proxy != null); Debug.Assert(_addr != null); _proxy.BeginWrite(_addr, writeBuffer); return(SocketOperation.Write); } else if (_state == StateProxyRead) { Debug.Assert(_proxy != null); readBuffer = _proxy.BeginRead(); return(SocketOperation.Read); } else if (_state == StateProxyConnected) { Debug.Assert(_proxy != null); _proxy.Finish(readBuffer); // TODO Return buffers to the pool readBuffer = ArraySegment <byte> .Empty; writeBuffer.Clear(); _state = StateConnected; } Debug.Assert(_state == StateConnected); return(SocketOperation.None); }
public void FinishWrite(IList <ArraySegment <byte> > buffer, ref int offset) { Debug.Assert(_writeEventArgs != null); Debug.Assert(offset == 0); if (_fd == null) { int count = buffer.GetByteCount(); // Assume all the data was sent for at-most-once semantics. _writeEventArgs = null; offset = count; return; } if (!_incoming && _state < StateConnected) { if (_writeEventArgs.SocketError != SocketError.Success) { var ex = new System.Net.Sockets.SocketException((int)_writeEventArgs.SocketError); if (Network.ConnectionRefused(ex)) { throw new ConnectionRefusedException(ex); } else { throw new ConnectFailedException(ex); } } return; } int ret; try { if (_writeEventArgs.SocketError != SocketError.Success) { throw new System.Net.Sockets.SocketException((int)_writeEventArgs.SocketError); } ret = _writeEventArgs.BytesTransferred; _writeEventArgs.SetBuffer(null, 0, 0); if (_writeEventArgs.BufferList != null && _writeEventArgs.BufferList != buffer) { _writeEventArgs.BufferList.Clear(); } _writeEventArgs.BufferList = null; } catch (System.Net.Sockets.SocketException ex) { if (Network.ConnectionLost(ex)) { throw new ConnectionLostException(ex); } else { throw new TransportException(ex); } } if (ret == 0) { throw new ConnectionLostException(); } Debug.Assert(ret > 0); Debug.Assert(ret == buffer.GetByteCount()); offset = ret; return; }
public void FinishRead(ref ArraySegment <byte> buffer, ref int offset) { if (_fd == null) { return; } int ret; try { if (_readEventArgs.SocketError != SocketError.Success) { throw new System.Net.Sockets.SocketException((int)_readEventArgs.SocketError); } ret = _readEventArgs.BytesTransferred; // TODO: Workaround for https://github.com/dotnet/corefx/issues/31182 if (_state != StateConnected && !(AssemblyUtil.IsMacOS && _fd.AddressFamily == AddressFamily.InterNetworkV6 && _fd.DualMode)) { _peerAddr = _readEventArgs.RemoteEndPoint; } } catch (System.Net.Sockets.SocketException ex) { if (Network.RecvTruncated(ex)) { // The message was truncated and the whole buffer is filled. We ignore // this error here, it will be detected at the connection level when // the Ice message size is checked against the buffer size. ret = buffer.Count; } else { if (Network.ConnectionLost(ex)) { throw new ConnectionLostException(ex); } else if (Network.ConnectionRefused(ex)) { throw new ConnectionRefusedException(ex); } else { throw new TransportException(ex); } } } if (ret == 0) { throw new ConnectionLostException(); } Debug.Assert(ret > 0); if (_state == StateNeedConnect) { Debug.Assert(_incoming); // // If we must connect, then we connect to the first peer that // sends us a packet. // bool connected = !_fd.ConnectAsync(_readEventArgs); Debug.Assert(connected); _state = StateConnected; // We're connected now if (_communicator.TraceLevels.Network >= 1) { _communicator.Logger.Trace(_communicator.TraceLevels.NetworkCat, $"connected {Transport} socket\n{this}"); } } buffer = buffer.Slice(0, ret); offset = ret; }