Пример #1
0
        private void SendPacket(BasicTunnelPacket packet)
        {
            if (IsTunnelEstablished)
            {
#if (DEBUG)
                Logger.Debug("Sending packet " + packet.ToString());
#endif
                byte[] sendBytes = packet.getBytes();
                _udpClient.Send(sendBytes, sendBytes.Length, _remoteEndpoint);
            }
            else
            {
                throw new ConnectionException("Cannot send packet [" + packet.ToString() + "], not currently synced with a peer");
            }
        }
Пример #2
0
        private void HandlePacket(BasicTunnelPacket packet)
        {
#if (DEBUG)
            Logger.Debug("Looking for handler for packet " + packet.ToString() + " from ip " + packet.ip);
#endif
            // data packets must come from the established IP
            if (packet.type == BasicTunnelPacket.PKT_TYPE_DATA && packet.ip.Equals(_remoteEndpoint))
            {
#if (DEBUG)
                Logger.Debug("Got a data packet");
#endif
                if (ProcessData != null)
                {
                    try
                    {
                        byte[] data = packet.data;
                        if (DecryptData != null)
                        {
                            try
                            {
                                DecryptData(ref data);
                            }
                            catch (Exception e)
                            {
                                Logger.Error("Encryption failed, shutting down tunnel : " + e.Message, e);
                                this.Close();
                            }
                        }
                        // a new thread needs to handle this upstream otherwise upstream can hang the whole process
                        Thread processDataThread = new Thread(() => ProcessData(data, Id))
                        {
                            IsBackground = true
                        };
                        processDataThread.Name = "processTunnelData[" + Id + "-" + processDataThread.ManagedThreadId + "]";
                        processDataThread.Start();
                    }
                    catch (Exception e)
                    {
                        Logger.Error("Failed to call processData on packet " + packet.ToString() + " : " + e.Message);
                    }
                }
                else
                {
                    Logger.Error("Cannot handle packet, no processData method");
                }
            }
            else if (packet.type == BasicTunnelPacket.PKT_TYPE_WAVE_RS)
            {
#if (DEBUG)
                Logger.Debug("Got a wave response from " + packet.ip + ", my address is " + ((StandardWaveTunnelRsPacket)packet).externalEndPoint + "/" + ((StandardWaveTunnelRsPacket)packet).internalEndPoint);
#endif
                if (_waver != null)
                {
                    _waver.ProcessWaveRs((StandardWaveTunnelRsPacket)packet);
                }
                else
                {
                    Logger.Error("Cannot process wave response, invalid wave handler");
                }
            }
            else if (packet.type == BasicTunnelPacket.PKT_TYPE_SYNC_RQ)
            {
#if (DEBUG)
                Logger.Debug("Got a sync request");
#endif
                if (_syncer != null)
                {
                    _syncer.ProcessSyncRq((StandardSyncRqTunnelPacket)packet);
                }
                else
                {
                    Logger.Error("Cannot process sync request, invalid sync handler");
                }
            }
            else if (packet.type == BasicTunnelPacket.PKT_TYPE_SYNC_RS)
            {
#if (DEBUG)
                Logger.Debug("Got a sync response");
#endif
                if (_syncer != null)
                {
                    _syncer.ProcessSyncRs((StandardSyncRsTunnelPacket)packet);
                }
                else
                {
                    Logger.Error("Cannot process sync response, invalid sync object");
                }
            }
            else if (packet.type == BasicTunnelPacket.PKT_TYPE_PONG && packet.ip.Equals(_remoteEndpoint))
            {
#if (DEBUG)
                Logger.Debug("Got a pong");
#endif
                if (_pinger != null)
                {
                    _pinger.ProcessPong((StandardPongTunnelPacket)packet);
                }
                else
                {
                    Logger.Error("Cannot process pong, invalid ping object");
                }
            }
            else if (packet.type == BasicTunnelPacket.PKT_TYPE_PING && packet.ip.Equals(_remoteEndpoint))
            {
#if (DEBUG)
                Logger.Debug("Got a ping");
#endif
                if (_pinger != null)
                {
                    _pinger.ProcessPing((StandardPingTunnelPacket)packet, _udpClient);
                    _lastPing = DateTime.Now.Ticks;
                }
                else
                {
                    Logger.Error("Cannot process ping, invalid ping object");
                }
            }
            else if (packet.type == BasicTunnelPacket.PKT_TYPE_NOP)
            {
#if (DEBUG)
                Logger.Debug("Got a nop");
#endif
            }
            else if (packet.type == BasicTunnelPacket.PKT_TYPE_CLOSE && packet.ip.Equals(_remoteEndpoint))
            {
#if (DEBUG)
                Logger.Debug("Got a close package, initialising close");
#endif
                this.Close();
            }
            else
            {
#if (DEBUG)
                Logger.Debug("Dropping unknown/invalid data packet " + packet.ToString());
#endif
            }
        }
Пример #3
0
        private void ListenForPackets()
        {
#if (DEBUG)
            Logger.Debug("Started UDP reading thread");
#endif
            while (true)
            {
                IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
                Byte[]     bytes            = null;
                try
                {
                    bytes = _udpClient.Receive(ref RemoteIpEndPoint);
                    BasicTunnelPacket packet = StandardUdpPacketFactory.instance.getPacket(bytes, RemoteIpEndPoint);
                    HandlePacket(packet);
                }
                catch (UnknownPacketException e)
                {
                    Logger.Error("Recieved an unknown packet type, dropping : " + e.Message);
                }
                catch (SocketException e)
                {
#if (DEBUG)
                    Logger.Debug("Caught a socket exception [" + e.ErrorCode + "] : " + e.Message);
#endif
                    if (e.ErrorCode == 10004) // Interrupted
                    {
#if (DEBUG)
                        Logger.Debug("Socket has been interrupted, shutting down");
#endif
                        this.Close();
                        break;
                    }
                    else if (e.ErrorCode == 10054) // Got ICMP connection closed ( we need to ignore this, hole punching causes these during init )
                    {
#if (DEBUG)
                        Logger.Debug("Remote host stated ICMP port closed, ignoring");
#endif
                    }
                    else if (e.ErrorCode == 10052) // Got a ttl expired which can happen since we are spamming both internal and external IP's, ignore
                    {
#if (DEBUG)
                        Logger.Debug("Ttl on one of our packets has expired, ignoring.");
#endif
                    }
                    else
                    {
                        Logger.Warn("Caught a socket exception [" + e.ErrorCode + "], this looks spurious, ignoring : " + e.Message);
                        Logger.Error("Caught a socket exception [" + e.ErrorCode + "], shutting down read thread : " + e.Message);
                        this.Close();
                        break;
                    }
                }
                catch (ThreadAbortException e)
                {
#if DEBUG
                    Logger.Debug("Thread is aborting, closing : " + e.Message);
#endif
                    this.Close();
                    break;
                }
                catch (Exception e)
                {
                    Logger.Error("Exception while reading from UDP socket, shutting down read thread : " + e.Message, e);
                    // Most likely the link has failed (this side) or the app is closing
                    // either way, close the thread for the moment
                    this.Close();
                    break;
                }
            }
        }
Пример #4
0
        private void ListenForPackets()
        {
            while (true)
            {
                IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
                Byte[]     bytes            = null;
                try
                {
                    bytes = _udpClient.Receive(ref RemoteIpEndPoint);
                    BasicTunnelPacket packet = StandardUdpPacketFactory.instance.getPacket(bytes, RemoteIpEndPoint);
                    if (packet.type == BasicTunnelPacket.PKT_TYPE_WAVE_RS)
                    {
#if (DEBUG)
                        Logger.Debug("Got a wave response from " + packet.ip + ", my address is " +
                                     ((StandardWaveTunnelRsPacket)packet).externalEndPoint + "/" +
                                     ((StandardWaveTunnelRsPacket)packet).internalEndPoint);
#endif
                        ProcessWaveRs((StandardWaveTunnelRsPacket)packet);
                        Logger.Debug("Shutting down wave listener");
                        break;
                    }
                    else
                    {
                        Logger.Error("Waiting for a wave response, but got unknown packet");
                        break;
                    }
                }
                catch (SocketException e)
                {
#if (DEBUG)
                    Logger.Debug("Caught a socket exception [" + e.ErrorCode + "] : " + e.Message);
#endif
                    if (e.ErrorCode == 10004) // Interrupted
                    {
#if (DEBUG)
                        Logger.Debug("Socket has been interrupted, shutting down");
#endif
                        _udpClient.Close();
                        break;
                    }
                    else if (e.ErrorCode == 10054)
                    // Got ICMP connection closed ( we need to ignore this, hole punching causes these during init )
                    {
#if (DEBUG)
                        Logger.Debug("Remote host stated ICMP port closed, ignoring");
#endif
                    }
                    else
                    {
                        Logger.Warn("Caught a socket exception [" + e.ErrorCode +
                                    "], this looks spurious, ignoring : " + e.Message);
                        Logger.Error("Caught a socket exception [" + e.ErrorCode + "], shutting down read thread : " +
                                     e.Message);
                        _udpClient.Close();
                        break;
                    }
                }
                catch (ThreadAbortException e)
                {
#if DEBUG
                    Logger.Debug("Thread is aborting, closing : " + e.Message);
#endif
                    _udpClient.Close();
                    break;
                }
                catch (Exception e)
                {
                    Logger.Error("Exception while reading from UDP socket, shutting down read thread : " + e.Message, e);
                    // Most likely the link has failed (this side) or the app is closing
                    // either way, close the thread for the moment
                    _udpClient.Close();
                    break;
                }
            }
        }