Example #1
0
 private void SendPacketEnvelope(SocketState connection, PacketEnvelope envelope)
 {
     byte[] sendBuffer = Packetizer.AssembleMessagePacket(envelope, connection.UseCompression, false, null, null);
     Stats.BytesSent += (UInt64)sendBuffer.Length;
     connection.Socket.Send(sendBuffer, sendBuffer.Length, SocketFlags.None);
 }
Example #2
0
        void ProcessReceivedData(SocketState connection, byte[] buffer, int bufferSize)
        {
            string sharedSecretString = connection.Peer.IsEncryptionNegotationComplete ? connection.Peer.KeyNegotiator.SharedSecretString : null;

            string commonSalt = null;

            if (connection.Peer.IsIncomming && connection.Peer.IsEncryptionNegotationComplete)
            {
                commonSalt = _route.BindingPreSharedKey;
            }
            else if (connection.Peer.IsOutgoing && connection.Peer.IsEncryptionNegotationComplete)
            {
                commonSalt = _route.EndpointPreSharedKey;
            }

            if (_route.TrafficType == TrafficType.Http)
            {
                HttpHeaderType httpHeaderType = HttpHeaderType.None;

                string httpHeader      = null;
                string httpRequestVerb = string.Empty;

                if (connection.HttpHeaderBuilder != string.Empty)
                {
                    //This is a continuation of a previously received fragmented header.
                    httpHeader     = (connection.HttpHeaderBuilder ?? string.Empty) + Encoding.UTF8.GetString(buffer);
                    httpHeaderType = HttpUtility.IsHttpHeader(httpHeader, out httpRequestVerb);
                }
                else
                {
                    httpHeaderType = HttpUtility.IsHttpHeader(buffer, bufferSize, out httpRequestVerb);

                    if (httpHeaderType != HttpHeaderType.None)
                    {
                        httpHeader = Encoding.UTF8.GetString(buffer);
                    }
                }

                if (httpHeaderType != HttpHeaderType.None)
                {
                    string lineBreak      = "";
                    int    endOfHeaderPos = HttpUtility.GetHttpHeaderEnd(httpHeader, out lineBreak);

                    if (endOfHeaderPos < 0)
                    {
                        throw new NotSupportedException(); //Not sure what to do yet.
                    }

                    if (endOfHeaderPos > bufferSize)
                    {
                        throw new InvalidOperationException(); //Not sure what to do yet.
                    }

                    httpHeader  = httpHeader.Substring(0, endOfHeaderPos).Trim(new char[] { '\r', '\n', ' ', '\0' });
                    httpHeader  = ApplyHttpHeaderRules(httpHeader, httpHeaderType, httpRequestVerb, lineBreak);
                    httpHeader += lineBreak + lineBreak; //Terminate the header.

                    int contentLength = bufferSize - (endOfHeaderPos - connection.HttpHeaderBuilder.Length);
                    connection.HttpHeaderBuilder = string.Empty;

                    byte[] fullReponse = new byte[httpHeader.Length + contentLength];

                    Buffer.BlockCopy(System.Text.Encoding.UTF8.GetBytes(httpHeader), 0, fullReponse, 0, httpHeader.Length);
                    if (contentLength > 0)
                    {
                        Buffer.BlockCopy(buffer, endOfHeaderPos, fullReponse, httpHeader.Length, contentLength);
                    }

                    if (connection.Peer.UsePackets)
                    {
                        //Console.WriteLine("--Send:{0}, Packet: {1}", route.Name, Encoding.UTF8.GetString(fullReponse.Take(fullReponse.Length).ToArray()));

                        byte[] sendBuffer = Packetizer.AssembleMessagePacket(fullReponse, fullReponse.Length, connection.Peer.UseCompression, connection.Peer.UseEncryption, sharedSecretString, commonSalt);
                        Stats.BytesSent += (UInt64)sendBuffer.Length;
                        connection.Peer.Socket.Send(sendBuffer, sendBuffer.Length, SocketFlags.None);
                        WaitForData(connection);
                    }
                    else
                    {
                        //Console.WriteLine("--Send:{0}, Raw: {1}", route.Name, Encoding.UTF8.GetString(fullReponse.Take(fullReponse.Length).ToArray()));

                        Stats.BytesSent += (UInt64)fullReponse.Length;
                        connection.Peer.Socket.Send(fullReponse, fullReponse.Length, SocketFlags.None);
                    }

                    return;
                }
            }

            if (connection.Peer.UsePackets)
            {
                //Console.WriteLine("--Send:{0}, Packet: {1}", route.Name, Encoding.UTF8.GetString(buffer.Take(bufferSize).ToArray()));

                byte[] sendBuffer = Packetizer.AssembleMessagePacket(buffer, bufferSize, connection.Peer.UseCompression, connection.Peer.UseEncryption, sharedSecretString, commonSalt);
                Stats.BytesSent += (UInt64)sendBuffer.Length;
                connection.Peer.Socket.Send(sendBuffer, sendBuffer.Length, SocketFlags.None);
            }
            else
            {
                //Console.WriteLine("--Send:{0}, Raw: {1}", route.Name, Encoding.UTF8.GetString(buffer.Take(bufferSize).ToArray()));

                Stats.BytesSent += (UInt64)bufferSize;
                connection.Peer.Socket.Send(buffer, bufferSize, SocketFlags.None);
            }
        }
Example #3
0
 private void SendPacketEnvelope(SocketState connection, PacketEnvelope envelope, string encryptionKey, string salt)
 {
     byte[] sendBuffer = Packetizer.AssembleMessagePacket(envelope, connection.UseCompression, true, encryptionKey, salt);
     Stats.BytesSent += (UInt64)sendBuffer.Length;
     connection.Socket.Send(sendBuffer, sendBuffer.Length, SocketFlags.None);
 }
Example #4
0
        private void OnDataReceived(IAsyncResult asyn)
        {
            SocketState connection = null;

            try
            {
                connection = (SocketState)asyn.AsyncState;
                connection.BytesReceived = connection.Socket.EndReceive(asyn);

                if (connection.BytesReceived == 0)
                {
                    CleanupConnection(connection);
                    return;
                }

                string sharedSecretString = connection.IsEncryptionNegotationComplete ? connection.KeyNegotiator.SharedSecretString : null;

                string commonSalt = null;
                if (connection.IsIncomming && connection.IsEncryptionNegotationComplete)
                {
                    commonSalt = _route.BindingPreSharedKey;
                }
                else if (connection.IsOutgoing && connection.IsEncryptionNegotationComplete)
                {
                    commonSalt = _route.EndpointPreSharedKey;
                }

                if (connection.UsePackets)
                {
                    //Console.WriteLine("--Recv:{0}, Packet: {1}", route.Name, Encoding.UTF8.GetString(connection.Buffer.Take(connection.BytesReceived).ToArray()));

                    List <PacketEnvelope> envelopes = Packetizer.DissasemblePacketData(this, connection, connection.UseCompression, connection.IsEncryptionNegotationComplete, sharedSecretString, commonSalt);
                    foreach (var envelope in envelopes)
                    {
                        if (envelope.Label == null)
                        {
                            if (connection.IsTunnelNegotationComplete)
                            {
                                //Console.WriteLine("--Recv: {0} {1}", envelope.Payload.Length, Encoding.UTF8.GetString(envelope.Payload.Take(envelope.Payload.Length).ToArray()));
                                ProcessReceivedData(connection, envelope.Payload, envelope.Payload.Length);
                            }
                            else
                            {
                                Stats.DroppedPreNegotiatePacket++;
                                //Console.WriteLine("--Dropped packet, tunnel negotation is not yet complete", route.Name);
                            }
                        }
                        else
                        {
                            ProcessPeerCommand(connection, envelope);
                        }
                    }
                }
                else
                {
                    //Console.WriteLine("--Recv:{0}, Raw: {1}", route.Name, Encoding.UTF8.GetString(connection.Buffer.Take(connection.BytesReceived).ToArray()));

                    //If we are supposed to use encryption, nut its not been initialized then we need to wait before processing the received data.
                    //This is because we do not yet have the information required to decrypt it.
                    //Try a spin lock first, then start sleeping.
                    if (connection.IsTunnelNegotationComplete == false)
                    {
                        WaitForData(connection);

                        int      spinCount = _route.SpinLockCount;
                        DateTime?startTime = null;

                        while (connection.IsTunnelNegotationComplete == false)
                        {
                            //TODO: This needs to timeout.
                            if (spinCount == 0)
                            {
                                startTime = DateTime.Now;
                            }
                            else if (startTime != null)
                            {
                                if ((DateTime.Now - ((DateTime)startTime)).TotalMilliseconds > _route.EncryptionInitilizationTimeoutMs)
                                {
                                    break;
                                }
                                Thread.Sleep(1);
                            }

                            spinCount--;
                        }
                    }

                    if (connection.IsTunnelNegotationComplete)
                    {
                        ProcessReceivedData(connection, connection.Buffer, connection.BytesReceived);
                    }
                    else
                    {
                        Stats.DroppedPreNegotiateRawData++;
                        Console.WriteLine("--Dropped Raw Data Segment", _route.Name);
                    }
                }

                WaitForData(connection);
            }
            catch (ObjectDisposedException)
            {
                if (connection != null)
                {
                    CleanupConnection(connection);
                }
                return;
            }
            catch (SocketException)
            {
                if (connection != null)
                {
                    CleanupConnection(connection);
                }
                return;
            }
            catch (Exception ex)
            {
                Singletons.EventLog.WriteEvent(new EventLogging.EventPayload
                {
                    Severity   = EventLogging.Severity.Error,
                    CustomText = "Failed to process received data.",
                    Exception  = ex
                });
            }
        }