public void HandlePackets() { IPEndPoint receive_ep = new IPEndPoint(IPAddress.Any, 0); var mtu_special = Encoding.ASCII.GetBytes("MTU "); while (!listener_stop.WaitOne(0)) { try { byte[] buf = Socket.Receive(ref receive_ep); byte[] tuple = EndPointToTuple(receive_ep); if (Sessions.ContainsKey(tuple)) { var session = Sessions[tuple]; bool mtu_probe = true; for (int i = 0; i < 4; i++) { if (buf[i] != mtu_special[i]) { mtu_probe = false; break; } } if (mtu_probe) { session.GoodMTUs.Add(buf.Length); session.LastMTUProbe = DateTime.Now; continue; } if (session.L7FragmentationCapable && !session.NegotiatingMTU) { session.HandleFragment(buf); } else { session.Push(buf); } } else { var session = new UdpSession(Socket, this, receive_ep); Message syn_msg = null; try { syn_msg = Message.Parse(buf); } catch (Exception ex) { Log.Info("Ignored improper connection attempt with message {0}/0x{1:X2}", syn_msg?.Type, syn_msg?.Subtype); continue; } if (syn_msg == null || syn_msg.Type != MessageType.Control || syn_msg.Subtype != UdpSession.SYN) { Log.Info("Ignored improper connection attempt with message {0}/0x{1:X2}", syn_msg?.Type, syn_msg?.Subtype); continue; } Sessions[tuple] = session; Utilities.StartThread(delegate { var syn_ack_msg = new Message(MessageType.Control, UdpSession.SYN_ACK); syn_ack_msg.Store["capabilities"] = new byte[] { (byte)UdpCapabilities.L7Fragmentation }; session.Send(syn_ack_msg.Serialize()); var ack_msg = session.ReceiveMessage(UdpSession.HANDSHAKE_TIMEOUT); if (ack_msg == null || ack_msg.Type != MessageType.Control || ack_msg.Subtype != UdpSession.ACK) { Log.Info("Ignored improper connection attempt with message {0}/0x{1:X2}", ack_msg?.Type, ack_msg?.Subtype); Sessions.Remove(tuple); return; } if (ack_msg.Store.ContainsKey("capabilities")) { session.L7FragmentationCapable = ack_msg.Store["capabilities"].Contains((byte)UdpCapabilities.L7Fragmentation); } Log.Info("Accepted UDP connection on {0}{1}", receive_ep, QueueConnections ? ", queueing session" : ""); if (session.L7FragmentationCapable) { Log.Info("Negotiating MTU..."); session.NegotiateMTU(); } if (QueueConnections) { Queue.Add(new UdpTunnel(session)); } }); } } catch (SocketException ex) { Log.Error(ex); } catch (Exception ex) { Log.Error(ex); } } }
internal void Close(UdpSession session) { Sessions.Remove(EndPointToTuple(session.EndPoint)); }