public BasicTunnelPacket getPacket(byte[] bytes, IPEndPoint ip) { BasicTunnelPacket packet; switch (bytes[BasicTunnelPacket.PKT_POS_TYPE]) { case BasicTunnelPacket.PKT_TYPE_PING: packet = new StandardPingTunnelPacket(); break; case BasicTunnelPacket.PKT_TYPE_PONG: packet = new StandardPongTunnelPacket(); break; case BasicTunnelPacket.PKT_TYPE_SYNC_RS: packet = new StandardSyncRsTunnelPacket(); break; case BasicTunnelPacket.PKT_TYPE_SYNC_RQ: packet = new StandardSyncRqTunnelPacket(); break; case BasicTunnelPacket.PKT_TYPE_WAVE_RS: packet = new StandardWaveTunnelRsPacket(); break; case BasicTunnelPacket.PKT_TYPE_WAVE_RQ: packet = new StandardWaveTunnelRqPacket(); break; case BasicTunnelPacket.PKT_TYPE_DATA: packet = new StandardTunnelDataPacket(); break; case BasicTunnelPacket.PKT_TYPE_NOP: packet = new StandardTunnelNopPacket(); break; case BasicTunnelPacket.PKT_TYPE_CLOSE: packet = new StandardCloseTunnelPacket(); break; default: throw new UnknownPacketException("Failed to determine packet type [" + bytes[BasicTunnelPacket.PKT_POS_TYPE] + "]"); } packet.processPacket(bytes, ip); return packet; }
public IPEndPoint WaitForSyncFromPeer(PeerInfo peer, int timeout, UdpClient udpClient) { long waitTime = timeout * 10000; long startTime = DateTime.Now.Ticks; Logger.Debug("Waiting for sync from peer " + peer + " to " + udpClient.Client.LocalEndPoint + " to establish tunnel " + Id); StandardTunnelNopPacket nop = new StandardTunnelNopPacket(); _expectedPeer = peer; _syncEvent.Reset(); _udpClient = udpClient; InitReceiverThread(); int attempts = 0; do { if (DateTime.Now.Ticks - startTime > waitTime) { Logger.Debug("Tunnel " + Id + ", sync Timeout : " + (DateTime.Now.Ticks - startTime)); throw new TimeoutException("Tunnel " + Id + ", timeout occured while waiting for sync from peer " + peer); } byte[] nopBytes = nop.getBytes(); if ((_syncTypes.Contains(SyncType.All) || _syncTypes.Contains(SyncType.Internal))) { Logger.Debug("Tunnel " + Id + ", sent nops, now waiting for sync request from internal of " + peer); foreach (var endPoint in peer.InternalEndPoints) { udpClient.Send(nopBytes, nopBytes.Length, endPoint); } } if (attempts > internalAttempts && (_syncTypes.Contains(SyncType.All) || _syncTypes.Contains(SyncType.External))) { Logger.Debug("Tunnel " + Id + ", sent nops, now waiting for sync request from external of " + peer); udpClient.Send(nopBytes, nopBytes.Length, peer.ExternalEndPoint); } // Facilitator is our last choice, only send here after 3 attempts at the other ones if (attempts >= externalAttempts && (_syncTypes.Contains(SyncType.All) || _syncTypes.Contains(SyncType.Facilitator))) { Logger.Debug("Tunnel " + Id + ", sent nops, now waiting for sync request from facilitator of " + peer); udpClient.Send(nopBytes, nopBytes.Length, peer.FacilitatorRepeatedEndPoint); } attempts++; } while (!_syncRqEvent.WaitOne(1000)); var activeIp = _lastSyncRqPacketIp; Logger.Debug("Tunnel " + Id + ", synchronisation with " + activeIp + " established"); return activeIp; }