public static Buffer?Compress(Buffer buf, int headerSize, int compressionLevel) { Debug.Assert(Supported()); // // Compress the message body, but not the header. // int uncompressedLen = buf.Size() - headerSize; byte[] data = buf.B.RawBytes(headerSize, uncompressedLen); int compressedLen = (int)((uncompressedLen * 1.01) + 600); byte[] compressed = new byte[compressedLen]; int rc = _compressBuffer(compressed, ref compressedLen, data, uncompressedLen, compressionLevel, 0, 0); if (rc == BZ_OUTBUFF_FULL) { return(null); } else if (rc < 0) { var ex = new Ice.CompressionException("BZ2_bzBuffToBuffCompress failed"); ex.Reason = GetBZ2Error(rc); throw ex; } // // Don't bother if the compressed data is larger than the // uncompressed data. // if (compressedLen >= uncompressedLen) { return(null); } var r = new Buffer(); r.Resize(headerSize + 4 + compressedLen, false); r.B.Position(0); // // Copy the header from the uncompressed stream to the // compressed one. // r.B.Put(buf.B.RawBytes(0, headerSize)); // // Add the size of the uncompressed stream before the // message body. // r.B.PutInt(buf.Size()); // // Add the compressed message body. // r.B.Put(compressed, 0, compressedLen); return(r); }
public void FinishWrite(Buffer buf) { Debug.Assert(_writeEventArgs != null); if (_fd == null) { buf.B.Position(buf.Size()); // Assume all the data was sent for at-most-once semantics. _writeEventArgs = null; return; } if (!_incoming && _state < StateConnected) { if (_writeEventArgs.SocketError != SocketError.Success) { var ex = new SocketException((int)_writeEventArgs.SocketError); if (Network.ConnectionRefused(ex)) { throw new Ice.ConnectionRefusedException(ex); } else { throw new Ice.ConnectFailedException(ex); } } return; } int ret; try { if (_writeEventArgs.SocketError != SocketError.Success) { throw new SocketException((int)_writeEventArgs.SocketError); } ret = _writeEventArgs.BytesTransferred; } catch (SocketException ex) { if (Network.ConnectionLost(ex)) { throw new Ice.ConnectionLostException(ex); } else { throw new Ice.SocketException(ex); } } if (ret == 0) { throw new Ice.ConnectionLostException(); } Debug.Assert(ret > 0); Debug.Assert(ret == buf.B.Limit()); buf.B.Position(buf.B.Position() + ret); }
public void FinishWrite(Buffer buf) { if (_fd == null) // Transceiver was closed { if (buf.Size() - buf.B.Position() < _maxSendPacketSize) { buf.B.Position(buf.B.Limit()); // Assume all the data was sent for at-most-once semantics. } return; } Debug.Assert(_fd != null && _writeEventArgs != null); if (_state < StateConnected && _state != StateProxyWrite) { return; } try { if (_writeEventArgs.SocketError != SocketError.Success) { throw new SocketException((int)_writeEventArgs.SocketError); } int ret = _writeEventArgs.BytesTransferred; _writeEventArgs.SetBuffer(null, 0, 0); if (ret == 0) { throw new Ice.ConnectionLostException(); } Debug.Assert(ret > 0); buf.B.Position(buf.B.Position() + ret); if (_state == StateProxyWrite) { Debug.Assert(_proxy != null); _state = ToState(_proxy.EndWrite(buf)); } } catch (SocketException ex) { if (Network.ConnectionLost(ex)) { throw new Ice.ConnectionLostException(ex); } throw new Ice.SocketException(ex); } catch (ObjectDisposedException ex) { throw new Ice.ConnectionLostException(ex); } }
public void CheckSendSize(Buffer buf) { // // The maximum packetSize is either the maximum allowable UDP packet size, or // the UDP send buffer size (which ever is smaller). // int packetSize = Math.Min(MaxPacketSize, _sndSize - UdpOverhead); if (packetSize < buf.Size()) { throw new Ice.DatagramLimitException(); } }
public static Buffer Uncompress(Buffer buf, int headerSize, int messageSizeMax) { Debug.Assert(Supported()); buf.B.Position(headerSize); int uncompressedSize = buf.B.GetInt(); if (uncompressedSize <= headerSize) { throw new Ice.IllegalMessageSizeException("compressed size <= header size"); } if (uncompressedSize > messageSizeMax) { Ex.ThrowMemoryLimitException(uncompressedSize, messageSizeMax); } int compressedLen = buf.Size() - headerSize - 4; byte[] compressed = buf.B.RawBytes(headerSize + 4, compressedLen); int uncompressedLen = uncompressedSize - headerSize; byte[] uncompressed = new byte[uncompressedLen]; int rc = _decompressBuffer(uncompressed, ref uncompressedLen, compressed, compressedLen, 0, 0); if (rc < 0) { throw new Ice.CompressionException($"BZ2_bzBuffToBuffDecompress failed\n{GetBZ2Error(rc)}"); } var r = new Buffer(); r.Resize(uncompressedSize, false); // // Copy the header from the compressed buffer to the uncompressed one. // r.B.Position(0); r.B.Put(buf.B.RawBytes(), 0, headerSize); r.B.Put(uncompressed); return(r); }
public bool StartWrite(Buffer buf, AsyncCallback callback, object state, out bool completed) { Debug.Assert(_fd != null); Debug.Assert(_writeEventArgs != null); if (!_incoming && _state < StateConnected) { Debug.Assert(_addr != null); completed = false; if (_sourceAddr != null) { _fd.Bind(_sourceAddr); } _writeEventArgs.UserToken = state; return(!_fd.ConnectAsync(_writeEventArgs)); } // The caller is supposed to check the send size before by calling checkSendSize Debug.Assert(Math.Min(MaxPacketSize, _sndSize - UdpOverhead) >= buf.Size()); Debug.Assert(buf.B.Position() == 0); bool completedSynchronously; try { _writeCallback = callback; if (_state == StateConnected) { _writeEventArgs.UserToken = state; _writeEventArgs.SetBuffer(buf.B.RawBytes(), 0, buf.B.Limit()); completedSynchronously = !_fd.SendAsync(_writeEventArgs); } else { if (_peerAddr == null) { throw new Ice.SocketException(); } _writeEventArgs.RemoteEndPoint = _peerAddr; _writeEventArgs.UserToken = state; _writeEventArgs.SetBuffer(buf.B.RawBytes(), 0, buf.B.Limit()); completedSynchronously = !_fd.SendToAsync(_writeEventArgs); } } catch (SocketException ex) { if (Network.ConnectionLost(ex)) { throw new Ice.ConnectionLostException(ex); } else { throw new Ice.SocketException(ex); } } completed = true; return(completedSynchronously); }
public void FinishRead(Buffer buf) { if (_fd == null) { return; } int ret; try { if (_readEventArgs.SocketError != SocketError.Success) { throw new 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 (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 = buf.Size(); } else { if (Network.ConnectionLost(ex)) { throw new Ice.ConnectionLostException(ex); } if (Network.ConnectionRefused(ex)) { throw new Ice.ConnectionRefusedException(ex); } else { throw new Ice.SocketException(ex); } } } if (ret == 0) { throw new Ice.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 (_instance.TraceLevel >= 1) { _instance.Logger.Trace(_instance.TraceCategory, $"connected {Transport()} socket\n{this}"); } } buf.Resize(ret, true); buf.B.Position(ret); }
public int Read(Buffer buf, ref bool hasMoreData) { if (!buf.B.HasRemaining()) { return(SocketOperation.None); } Debug.Assert(buf.B.Position() == 0); Debug.Assert(_fd != null); int packetSize = Math.Min(MaxPacketSize, _rcvSize - UdpOverhead); buf.Resize(packetSize, true); buf.B.Position(0); int ret; while (true) { try { EndPoint?peerAddr = _peerAddr; if (peerAddr == null) { if (_addr.AddressFamily == AddressFamily.InterNetwork) { peerAddr = new IPEndPoint(IPAddress.Any, 0); } else { Debug.Assert(_addr.AddressFamily == AddressFamily.InterNetworkV6); peerAddr = new IPEndPoint(IPAddress.IPv6Any, 0); } } // TODO: Workaround for https://github.com/dotnet/corefx/issues/31182 if (_state == StateConnected || (AssemblyUtil.IsMacOS && _fd.AddressFamily == AddressFamily.InterNetworkV6 && _fd.DualMode)) { ret = _fd.Receive(buf.B.RawBytes(), 0, buf.B.Limit(), SocketFlags.None); } else { ret = _fd.ReceiveFrom(buf.B.RawBytes(), 0, buf.B.Limit(), SocketFlags.None, ref peerAddr); _peerAddr = (IPEndPoint)peerAddr; } break; } catch (SocketException e) { if (Network.RecvTruncated(e)) { // 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 = buf.Size(); break; } if (Network.Interrupted(e)) { continue; } if (Network.WouldBlock(e)) { return(SocketOperation.Read); } if (Network.ConnectionLost(e)) { throw new Ice.ConnectionLostException(); } else { throw new Ice.SocketException(e); } } catch (Exception e) { throw new Ice.SyscallException(e); } } if (ret == 0) { throw new Ice.ConnectionLostException(); } if (_state == StateNeedConnect) { Debug.Assert(_incoming); // // If we must connect, then we connect to the first peer that sends us a packet. // Debug.Assert(_peerAddr != null); bool connected = Network.DoConnect(_fd, _peerAddr, null); Debug.Assert(connected); _state = StateConnected; // We're connected now if (_instance.TraceLevel >= 1) { _instance.Logger.Trace(_instance.TraceCategory, $"connected {Transport()} socket\n{this}"); } } buf.Resize(ret, true); buf.B.Position(ret); return(SocketOperation.None); }
public int Write(Buffer buf) { if (!buf.B.HasRemaining()) { return(SocketOperation.None); } Debug.Assert(buf.B.Position() == 0); Debug.Assert(_fd != null && _state >= StateConnected); // The caller is supposed to check the send size before by calling checkSendSize Debug.Assert(Math.Min(MaxPacketSize, _sndSize - UdpOverhead) >= buf.Size()); int ret; while (true) { try { if (_state == StateConnected) { ret = _fd.Send(buf.B.RawBytes(), 0, buf.Size(), SocketFlags.None); } else { if (_peerAddr == null) { throw new Ice.SocketException(); } ret = _fd.SendTo(buf.B.RawBytes(), 0, buf.Size(), SocketFlags.None, _peerAddr); } break; } catch (SocketException ex) { if (Network.Interrupted(ex)) { continue; } if (Network.WouldBlock(ex)) { return(SocketOperation.Write); } if (Network.ConnectionLost(ex)) { throw new Ice.ConnectionLostException(ex); } else { throw new Ice.SocketException(ex); } } catch (Exception e) { throw new Ice.SyscallException(e); } } Debug.Assert(ret > 0); Debug.Assert(ret == buf.B.Limit()); buf.B.Position(buf.B.Limit()); return(SocketOperation.None); }