public void SendPacket(int command, ByteBuffer payload) { ByteBuffer buffer = ByteBuffer.Allocate(1 + 2 + payload.Remaining); /* Set IV. */ this.session.ShannonSend.nonce(IntUtils.ToBytes(this.session.KeySendIv)); /* Build packet. */ buffer.Put((byte)command); buffer.PutShort((short)payload.Remaining); buffer.Put(payload.ToArray()); byte[] bytes = buffer.ToArray(); byte[] mac = new byte[4]; /* Encrypt packet and get MAC. */ this.session.ShannonSend.encrypt(bytes); this.session.ShannonSend.finish(mac); buffer = ByteBuffer.Allocate(buffer.Position + 4); buffer.Put(bytes); buffer.Put(mac); buffer.Flip(); /* Send encrypted packet. */ this.Send(buffer); /* Increment IV. */ this.session.KeySendIv++; }
protected virtual void OnReceivePacketHeaderReceived(IAsyncResult asyn) { byte[] header = (byte[])asyn.AsyncState; int command, payloadLength, macLength = 4; // TODO: Find a good way to implement detection of closed socket here, // so that the function doesn't extrapolate incorrect data from null data. /* Set IV. */ this.session.ShannonRecv.nonce(IntUtils.ToBytes(this.session.KeyRecvIv)); /* Decrypt header. */ this.session.ShannonRecv.decrypt(header); /* Get command and payload length from header. */ ByteBuffer headerBuffer = ByteBuffer.Wrap(header); command = headerBuffer.Get() & 0xff; payloadLength = headerBuffer.GetShort() & 0xffff; /* Allocate buffer. Account for MAC. */ byte[] bytes = new byte[payloadLength + macLength]; //ByteBuffer buffer = ByteBuffer.Wrap(bytes); /* Limit buffer to payload length, so we can read the payload. */ //buffer.Limit = payloadLength; try{ this.Receive(bytes, 0, payloadLength); ////for(int n = payloadLength, r; n > 0 && (r = this.channel.Client.Receive(buffer)) > 0; n -= r); //int n = 0; //int r = -1; //while ((n < payloadLength) && (r != 0)) //{ // r = this.client.Client.Receive(bytes, n, payloadLength - n, SocketFlags.None); // n += r; //} } catch (IOException e) { throw new ProtocolException("Failed to read payload!", e); } /* Extend it again to payload and mac length. */ //buffer.Limit = payloadLength + macLength; try { this.Receive(bytes, payloadLength, macLength); ////for(int n = macLength, r; n > 0 && (r = this.channel.Read(buffer)) > 0; n -= r); //int n = payloadLength; //int r = -1; //while ((n < bytes.Length) && (r != 0)) //{ // r = this.Receive(bytes, n, bytes.Length - n); // n += r; //} } catch (IOException e) { throw new ProtocolException("Failed to read MAC!", e); } /* Decrypt payload. */ this.session.ShannonRecv.decrypt(bytes); /*Allocate buffer*/ ByteBuffer buffer = ByteBuffer.Wrap(bytes); /* Get payload bytes from buffer (throw away MAC). */ byte[] payload = new byte[payloadLength]; buffer.Flip(); buffer.Get(payload); /* Increment IV. */ this.session.KeyRecvIv++; /* Fire events. */ foreach (ICommandListener listener in this.listeners) { listener.CommandReceived(command, payload); } ReceivePacket(); }