override protected bool HandleOutgoing(ICopyable app_data, out ICopyable data) { MemBlock buffer = null; data = null; int written = 1; lock(_buffer_sync) { if(app_data != null) { int count = app_data.CopyTo(_buffer, 0); written = _ssl.Write(_buffer, count); } if(written > 0) { int count = _write.Read(_buffer, _buffer.Length); if(count <= 0) { // This really shouldn't ever happen ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, this + " error"); data = null; return false; } buffer = MemBlock.Copy(_buffer, 0, count); } } if(written > 0) { // Timer becomes -1 when there are no more control messages long to = _ssl.GetTimeout(); if(to >= 0) { HandleWouldBlock(); } if(buffer != null) { data = new CopyList(PType, Header, buffer); return true; } } // If the write failed, then Dtls is either waiting for a control message // or has a control message to send var error = _ssl.GetError(written); if(error == SslError.SSL_ERROR_WANT_READ) { HandleWouldBlock(); } else if(error == SslError.SSL_ERROR_SSL) { var ose = new OpenSslException(); Close("Received unrecoverable error: " + ose.ToString()); throw ose; } else { ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, "Send other"); } data = null; return false; }
override protected bool HandleIncoming(MemBlock data, out MemBlock app_data) { app_data = null; int count = 0; lock(_buffer_sync) { if(data != null) { data.CopyTo(_buffer, 0); _read.Write(_buffer, data.Length); } count = _ssl.Read(_buffer, _buffer.Length); if(count > 0) { app_data = MemBlock.Copy(_buffer, 0, count); } } if(app_data != null) { // If the read was successful, Dtls has received an incoming data // message and decrypted it return true; } else { SslError error = _ssl.GetError(count); if(error == SslError.SSL_ERROR_WANT_READ) { if(SslState == SslState.OK) { UpdateState(States.Active); // In the SslCtx verify, there's no way to get the underlying Sender _ch.Verify(RemoteCertificate, Sender); } HandleWouldBlock(); } else if(error == SslError.SSL_ERROR_SSL) { var ose = new OpenSslException(); Close("Received unrecoverable error: " + ose.ToString()); throw ose; } else if(error == SslError.SSL_ERROR_ZERO_RETURN) { Close("Received clean close notification"); } else { ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, "Receive other: " + error); } } return false; }