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 } }