private static IceCandidate GatherSRPassiveCandidate(IPAddress localIPAddress) { // local endpoint IPEndPoint localEndpoint = new IPEndPoint(localIPAddress, 0); // listening socket Socket passiveListeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); passiveListeningSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); passiveListeningSocket.Bind(localEndpoint); // update localEndpoint with binded Port localEndpoint = (IPEndPoint)passiveListeningSocket.LocalEndPoint; // STUN socket Socket passiveSTUNSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); passiveSTUNSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); passiveSTUNSocket.Bind(localEndpoint); // get defined STUN servers List<IPEndPoint> definedSTUNServers = GetDefinedSTUNServers(); // servers defined? if (definedSTUNServers.Count > 0) { // use first server IPEndPoint STUNEndPoint = definedSTUNServers[0]; // try to connect try { passiveSTUNSocket.Connect(STUNEndPoint); } catch (Exception e1) { //Console.WriteLine(e1.Message); // use second STUN server, if defined if (definedSTUNServers.Count == 2) { STUNEndPoint = definedSTUNServers[1]; // try to connect try { passiveSTUNSocket.Connect(STUNEndPoint); } catch (Exception e2) { //Console.WriteLine(e2.Message); // could not establish a connection to a STUN server return null; } } } } // no STUN servers defined else return null; // get public mapping IPEndPoint publicMapping = GetPublicMapping(passiveSTUNSocket); // save data in candidate object IpAddressPort passiveIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, publicMapping.Address, (ushort)publicMapping.Port); IceCandidate passiveCandidate = new IceCandidate(passiveIpAddressPort, Overlay_Link.TLS_TCP_with_FH); passiveCandidate.cand_type = CandType.tcp_srflx; passiveCandidate.rel_addr_port = new IpAddressPort(AddressType.IPv4_Address, localEndpoint.Address, (ushort)localEndpoint.Port); passiveCandidate.passiveListeningSocket = passiveListeningSocket; passiveCandidate.passiveSTUNSocket = passiveSTUNSocket; // TCP Type passiveCandidate.tcpType = TcpType.Passive; // TCP ICE extension IceExtension iceExtension = new IceExtension(); iceExtension.name = Encoding.UTF8.GetBytes("tcptype"); iceExtension.value = Encoding.UTF8.GetBytes("passive"); passiveCandidate.extension_list.Add(iceExtension); return passiveCandidate; }
private static IceCandidate GatherHostPassiveCandidate(IPAddress localIPAddress) { // local endpoint IPEndPoint localEndpoint = new IPEndPoint(localIPAddress, 0); Socket passiveListeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); passiveListeningSocket.Bind(localEndpoint); // update localEndpoint with binded Port localEndpoint = (IPEndPoint)passiveListeningSocket.LocalEndPoint; // save data in candidate object IpAddressPort passiveIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, localEndpoint.Address, (ushort)localEndpoint.Port); IceCandidate passiveCandidate = new IceCandidate(passiveIpAddressPort, Overlay_Link.TLS_TCP_with_FH); passiveCandidate.cand_type = CandType.tcp_host; passiveCandidate.passiveListeningSocket = passiveListeningSocket; // TCP Type passiveCandidate.tcpType = TcpType.Passive; // TCP ICE extension IceExtension iceExtension = new IceExtension(); iceExtension.name = Encoding.UTF8.GetBytes("tcptype"); iceExtension.value = Encoding.UTF8.GetBytes("passive"); passiveCandidate.extension_list.Add(iceExtension); return passiveCandidate; }
private static IceCandidate GatherHostSOCandidate(IPAddress localIPAddress) { // local endpoint IPEndPoint localEndpoint = new IPEndPoint(localIPAddress, 0); // listening socket Socket soListeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); soListeningSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); soListeningSocket.Bind(localEndpoint); // update localEndpoint with binded Port localEndpoint = (IPEndPoint)soListeningSocket.LocalEndPoint; // connecting socket Socket soConnectingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); soConnectingSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); soConnectingSocket.Bind(localEndpoint); // save data in candidate object IpAddressPort soIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, localEndpoint.Address, (ushort)localEndpoint.Port); IceCandidate soCandidate = new IceCandidate(soIpAddressPort, Overlay_Link.TLS_TCP_with_FH); soCandidate.cand_type = CandType.tcp_host; soCandidate.soListeningSocket = soListeningSocket; soCandidate.soConnectingSocket = soConnectingSocket; // TCP Type soCandidate.tcpType = TcpType.SO; // TCP ICE extension IceExtension iceExtension = new IceExtension(); iceExtension.name = Encoding.UTF8.GetBytes("tcptype"); iceExtension.value = Encoding.UTF8.GetBytes("so"); soCandidate.extension_list.Add(iceExtension); return soCandidate; }
private static byte[] ComputeFoundation(IceCandidate candidate) // checked { /* RFC 5245, ICE, Section 4.1.1.3 Finally, the agent assigns each candidate a foundation. The foundation is an identifier, scoped within a session. Two candidates MUST have the same foundation ID when all of the following are true: o they are of the same type (host, relayed, server reflexive, or peer reflexive). o their bases have the same IP address (the ports can be different). o for reflexive and relayed candidates, the STUN or TURN servers used to obtain them have the same IP address. o they were obtained using the same transport protocol (TCP, UDP, etc.). Similarly, two candidates MUST have different foundations if their types are different, their bases have different IP addresses, the STUN or TURN servers used to obtain them have different IP addresses, or their transport protocols are different. */ // type and transport protocol are both included in cand_type enum // and the candidates are always gathered from same servers (defined in config) // so we can build a foundation string out of the cand_type and the IP Address of the base, if a base exists (no host candidate) string candType = candidate.cand_type.ToString(); string baseIPAddress = ""; // if candidate has base (no host candidate) if (candidate.rel_addr_port != null) baseIPAddress = candidate.rel_addr_port.ipaddr.ToString(); string foundation = candType + baseIPAddress; return Encoding.ASCII.GetBytes(foundation); }
// HOST METHODS private static IceCandidate GatherHostActiveCandidate(IPAddress localIPAddress) { IPEndPoint localEndpoint = new IPEndPoint(localIPAddress, 0); //Socket activeConnectingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //// here is no bind, because active candidates don't have to be physically allocated here (allocation in connectivity checks) //activeConnectingSocket.Bind(localEndpoint); // TEST /* RFC 6544 (ICE TCP), Section 3: In the case of active candidates, both IP address and port are present, but the port is meaningless (it is there only for making encoding of active candidates consistent with the other candidate types and is ignored by the peer). As a consequence, active candidates do not need to be physically allocated at the time of address gathering. Rather, the physical allocations, which occur as a consequence of a connection attempt, occur at the time of the connectivity checks. */ // save data in candidate object IpAddressPort activeIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, localEndpoint.Address, (ushort)localEndpoint.Port); IceCandidate activeCandidate = new IceCandidate(activeIpAddressPort, Overlay_Link.TLS_TCP_with_FH); activeCandidate.cand_type = CandType.tcp_host; //activeCandidate.activeConnectingSocket = activeConnectingSocket; // TEST: in PerformCheck // TCP Type activeCandidate.tcpType = TcpType.Active; // TCP ICE extension IceExtension iceExtension = new IceExtension(); iceExtension.name = Encoding.UTF8.GetBytes("tcptype"); iceExtension.value = Encoding.UTF8.GetBytes("active"); activeCandidate.extension_list.Add(iceExtension); return activeCandidate; }
private static IceCandidate GatherNAPassiveCandidate(IPAddress localIPAddress) { // local endpoint IPEndPoint localEndpoint = new IPEndPoint(localIPAddress, 0); // only one listening socket, because there is no need to use a STUN server. We get the IP and Port from the NAT using UPnP Socket passiveListeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); passiveListeningSocket.Bind(localEndpoint); // update localEndpoint with binded Port localEndpoint = (IPEndPoint)passiveListeningSocket.LocalEndPoint; // check if UPnP is available UPnP upnp = new UPnP(); bool foundUPnPDevice = false; try { foundUPnPDevice = upnp.Discover(localIPAddress); } catch (Exception e) { //Console.WriteLine(e.Message); return null; } // IPEndPoint for public mapping IPEndPoint publicMapping = null; // found UPnP internet gateway device? if (foundUPnPDevice) { // try to get public IP and to add a port mapping try { string publicIP = upnp.GetExternalIP().ToString(); // we can use the local Port for the public NAT port mapping too bool addedPortMapping = upnp.AddPortMapping((ushort)localEndpoint.Port, (ushort)localEndpoint.Port, ProtocolType.Tcp, "RELOAD ICE TCP Port mapping"); if (addedPortMapping && !string.IsNullOrEmpty(publicIP)) { publicMapping = new IPEndPoint(IPAddress.Parse(publicIP), localEndpoint.Port); } else return null; } catch (Exception e) { //Console.WriteLine(e.Message); return null; } } // no UPnP IGD found else return null; // got public mapping? if (publicMapping == null) return null; // save data in candidate object IpAddressPort passiveIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, publicMapping.Address, (ushort)publicMapping.Port); IceCandidate passiveCandidate = new IceCandidate(passiveIpAddressPort, Overlay_Link.TLS_TCP_with_FH); passiveCandidate.cand_type = CandType.tcp_nat; passiveCandidate.rel_addr_port = new IpAddressPort(AddressType.IPv4_Address, localEndpoint.Address, (ushort)localEndpoint.Port); passiveCandidate.passiveListeningSocket = passiveListeningSocket; // TCP Type passiveCandidate.tcpType = TcpType.Passive; // TCP ICE extension IceExtension iceExtension = new IceExtension(); iceExtension.name = Encoding.UTF8.GetBytes("tcptype"); iceExtension.value = Encoding.UTF8.GetBytes("passive"); passiveCandidate.extension_list.Add(iceExtension); return passiveCandidate; }
public bool Equals(IceCandidate cand) { // If parameter is null return false: if ((object)cand == null) { return false; } // Return true if the fields match: return (addr_port.port == cand.addr_port.port) && (priority == cand.priority) && (cand_type == cand.cand_type) && (tcpType == cand.tcpType); }
public static void CloseAllCandidateSockets(IceCandidate candidate) { if (candidate.activeConnectingSocket != null) candidate.activeConnectingSocket.Close(); if (candidate.passiveAcceptedSocket != null) candidate.passiveAcceptedSocket.Close(); if (candidate.passiveListeningSocket != null) candidate.passiveListeningSocket.Close(); if (candidate.passiveSTUNSocket != null) candidate.passiveSTUNSocket.Close(); if (candidate.soAcceptedSocket != null) candidate.soAcceptedSocket.Close(); if (candidate.soConnectingSocket != null) candidate.soConnectingSocket.Close(); if (candidate.soListeningSocket != null) candidate.soListeningSocket.Close(); if (candidate.soSTUN1Socket != null) candidate.soSTUN1Socket.Close(); if (candidate.soSTUN2Socket != null) candidate.soSTUN2Socket.Close(); }
//public static void PrintCandidate(IceCandidate iceCandidate) //{ // Console.WriteLine("{0}:{1}", iceCandidate.addr_port.ipaddr.ToString(), iceCandidate.addr_port.port); //} public static void PrintCandidate(IceCandidate iceCandidate) { Console.WriteLine("{0}:{1} ({2})", iceCandidate.addr_port.ipaddr.ToString(), iceCandidate.addr_port.port, iceCandidate.tcpType.ToString()); if (iceCandidate.rel_addr_port != null) { Console.WriteLine("\tBase: " + iceCandidate.rel_addr_port.ipaddr.ToString() + ":" + iceCandidate.rel_addr_port.port); } }
public CandidatePair(IceCandidate localCandidate, IceCandidate remoteCandidate) { this.localCandidate = localCandidate; this.remoteCandidate = remoteCandidate; this.valid = false; this.nominated = false; this.state = CandidatePairState.Frozen; this.pairPriority = 0; /* RFC 5245, ICE, Section 5.7.4 Each candidate pair in the check list has a foundation and a state. The foundation is the combination of the foundations of the local and remote candidates in the pair. */ if (localCandidate.foundation != null && remoteCandidate.foundation != null) { this.pairFoundation = new byte[localCandidate.foundation.Length + remoteCandidate.foundation.Length]; // first copy local candidate foundation Array.Copy(localCandidate.foundation, 0, this.pairFoundation, 0, localCandidate.foundation.Length); // then copy remote candidate foundation Array.Copy(remoteCandidate.foundation, 0, this.pairFoundation, localCandidate.foundation.Length, remoteCandidate.foundation.Length); } else this.pairFoundation = null; }
public static IceCandidate CreateBootstrapCandidate(IPAddress localIPAddress, int port) { // save data in candidate object IpAddressPort bootstrapIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, localIPAddress, (ushort)port); IceCandidate bootstrapCandidate = new IceCandidate(bootstrapIpAddressPort, Overlay_Link.TLS_TCP_with_FH); bootstrapCandidate.cand_type = CandType.tcp_bootstrap; // TCP Type bootstrapCandidate.tcpType = TcpType.Passive; // TCP ICE extension IceExtension iceExtension = new IceExtension(); iceExtension.name = Encoding.UTF8.GetBytes("tcptype"); iceExtension.value = Encoding.UTF8.GetBytes("passive"); bootstrapCandidate.extension_list.Add(iceExtension); // set other preference and foundation bootstrapCandidate.otherPreference = 8191; bootstrapCandidate.foundation = ComputeFoundation(bootstrapCandidate); return bootstrapCandidate; }
public override RELOAD_MessageBody FromReader(ReloadMessage rm, BinaryReader reader, long reload_msg_size) { /* try to read the packet as a AppAttachReqAns packet */ try { byte length; RELOAD_MsgCode = (RELOAD_MessageCode)(UInt16)IPAddress.NetworkToHostOrder(reader.ReadInt16()); UInt32 message_len = (UInt32)(IPAddress.HostToNetworkOrder((int)reader.ReadInt32())); /* The username fragment (from ICE), we set it to zero length in NO-ICE */ length = reader.ReadByte(); if (length != 0) ufrag = reader.ReadBytes(length); reload_msg_size = reload_msg_size - (length + 1); /* The The ICE password, we set it to zero length in NO-ICE */ length = reader.ReadByte(); if (length != 0) password = reader.ReadBytes(length); reload_msg_size = reload_msg_size - (length + 1); /* An active/passive/actpass attribute from RFC 4145 [RFC4145]. */ length = reader.ReadByte(); if (length != 0) role = reader.ReadBytes(length); reload_msg_size = reload_msg_size - (length + 1); while (reload_msg_size > 0) { AddressType type = (AddressType)reader.ReadByte(); IPAddress ip; length = reader.ReadByte(); --reload_msg_size; switch (type) { case AddressType.IPv4_Address: if (length != 6) return null; ip = new IPAddress(reader.ReadBytes(4)); reload_msg_size = reload_msg_size - length; break; case AddressType.IPv6_Address: if (length != 18) return null; ip = new IPAddress(reader.ReadBytes(16)); reload_msg_size = reload_msg_size - length; break; default: throw new System.Exception(String.Format("Invalid address type {0} in AppAttachReqAns!", type)); } UInt16 port = (ushort)IPAddress.NetworkToHostOrder(reader.ReadInt16()); Overlay_Link overlay_link = (Overlay_Link)reader.ReadByte(); IceCandidate candidate = new IceCandidate(new IpAddressPort(type, ip, port), overlay_link); int fond_length = reader.ReadByte(); candidate.foundation = reader.ReadBytes(fond_length); reload_msg_size = reload_msg_size - fond_length - 1; candidate.priority = (UInt32)IPAddress.NetworkToHostOrder(reader.ReadInt32()); candidate.cand_type = (CandType)reader.ReadByte(); reload_msg_size = reload_msg_size - 8; switch (candidate.cand_type) { case CandType.tcp_host: /* do nothing */ break; case CandType.tcp_prflx: case CandType.tcp_relay: case CandType.tcp_srflx: type = (AddressType)reader.ReadByte(); byte rel_length = reader.ReadByte(); --reload_msg_size; switch (type) { case AddressType.IPv4_Address: if (rel_length != 6) return null; ip = new IPAddress(reader.ReadBytes(4)); reload_msg_size = reload_msg_size - length; break; case AddressType.IPv6_Address: if (rel_length != 18) return null; ip = new IPAddress(reader.ReadBytes(16)); reload_msg_size = reload_msg_size - rel_length; break; default: throw new System.Exception(String.Format("Invalid rel address type {0} in AppAttachReqAns!", type)); } port = (ushort)IPAddress.NetworkToHostOrder(reader.ReadInt16()); candidate.rel_addr_port = new IpAddressPort(type, ip, port); break; } ice_candidates.Add(candidate); } } catch (Exception ex) { throw ex; } return this; }
public List<IceCandidate> IPAddressToIceCandidate(IPAddress ip, int portNum) { List<IceCandidate> ice_candidates = new List<IceCandidate>(); if (ip == null) return null; /* exclude IPv6 addresses for now */ if (ip.AddressFamily == AddressFamily.InterNetworkV6) return null; /* Setup an TCP candidate first */ IceCandidate candidate = new IceCandidate(new IpAddressPort(ip.AddressFamily == AddressFamily.InterNetworkV6 ? AddressType.IPv6_Address : AddressType.IPv4_Address, ip, (UInt16)portNum), Overlay_Link.TLS_TCP_FH_NO_ICE); /* when sending an AppAttachReqAns, form one candidate with a priority value of (2^24)*(126)+(2^8)*(65535)+(2^0)*(256-1) that specifies the UDP port being listened to and another one with the TCP port. */ ice_candidates.Add(candidate); /* same on UDP with same port number */ IceCandidate candidate2 = new IceCandidate(new IpAddressPort(ip.AddressFamily == AddressFamily.InterNetworkV6 ? AddressType.IPv6_Address : AddressType.IPv4_Address, ip, (UInt16)portNum), Overlay_Link.DLTS_UDP_SR_NO_ICE); ice_candidates.Add(candidate2); return ice_candidates; }
public override RELOAD_MessageBody FromReader(ReloadMessage rm, BinaryReader reader, long reload_msg_size) { /* try to read the packet as a AttachReqAns packet */ try { byte length; RELOAD_MsgCode = (RELOAD_MessageCode)(UInt16)IPAddress.NetworkToHostOrder(reader.ReadInt16()); UInt32 message_len = (UInt32)(IPAddress.HostToNetworkOrder((int)reader.ReadInt32())); /* The username fragment (from ICE), we set it to zero length in NO-ICE */ length = reader.ReadByte(); if (length != 0) ufrag = reader.ReadBytes(length); reload_msg_size -= (length + 1); /* The The ICE password, we set it to zero length in NO-ICE */ length = reader.ReadByte(); if (length != 0) password = reader.ReadBytes(length); reload_msg_size -= (length + 1); /* An active/passive/actpass attribute from RFC 4145 [RFC4145]. */ length = reader.ReadByte(); if (length != 0) role = reader.ReadBytes(length); reload_msg_size -= (length + 1); long ice_length = (UInt16)IPAddress.NetworkToHostOrder(reader.ReadInt16()); reload_msg_size -= (ice_length + 2); while (ice_length > 1) //size of bool which follows { AddressType type = (AddressType)reader.ReadByte(); --ice_length; IPAddress ip; length = reader.ReadByte(); --ice_length; switch (type) { case AddressType.IPv4_Address: if (length != 6) return null; ip = new IPAddress(reader.ReadBytes(4)); ice_length -= length; break; case AddressType.IPv6_Address: if (length != 18) return null; ip = new IPAddress(reader.ReadBytes(16)); ice_length -= length; break; default: throw new System.Exception(String.Format("Invalid address type {0} in AttachReqAns!", type)); } UInt16 port = (ushort)IPAddress.NetworkToHostOrder(reader.ReadInt16()); ice_length -= 2; Overlay_Link overlay_link = (Overlay_Link)reader.ReadByte(); --ice_length; IceCandidate candidate = new IceCandidate(new IpAddressPort(type, ip, port), overlay_link); int fond_length = reader.ReadByte(); candidate.foundation = reader.ReadBytes(fond_length); ice_length -= (fond_length - 1); candidate.priority = (UInt32)IPAddress.NetworkToHostOrder(reader.ReadInt32()); ice_length -= 4; candidate.cand_type = (CandType)reader.ReadByte(); --ice_length; switch (candidate.cand_type) { case CandType.tcp_host: /* do nothing */ break; case CandType.tcp_prflx: case CandType.tcp_nat: // new case CandType.tcp_relay: case CandType.tcp_srflx: type = (AddressType)reader.ReadByte(); byte rel_length = reader.ReadByte(); //--ice_length; ice_length -= 2; // markus switch (type) { case AddressType.IPv4_Address: if (rel_length != 6) return null; ip = new IPAddress(reader.ReadBytes(4)); ice_length -= rel_length; break; case AddressType.IPv6_Address: if (rel_length != 18) return null; ip = new IPAddress(reader.ReadBytes(16)); ice_length -= rel_length; break; default: throw new System.Exception(String.Format("Invalid rel address type {0} in AttachReqAns!", type)); } port = (ushort)IPAddress.NetworkToHostOrder(reader.ReadInt16()); ice_length -= 2; candidate.rel_addr_port = new IpAddressPort(type, ip, port); break; } /* // now read ice extension length long ice_extension_size = (UInt16)IPAddress.NetworkToHostOrder(reader.ReadInt16()); if (ice_extension_size != 0) { //skip ice extension length reader.ReadBytes((int)ice_extension_size); } ice_length -= (ice_extension_size + 2); */ #region markus // all new attributes for TCP ICE // type preference candidate.typePreference = (UInt32)IPAddress.NetworkToHostOrder(reader.ReadInt32()); ice_length -= 4; // local preference candidate.localPreference = (UInt32)IPAddress.NetworkToHostOrder(reader.ReadInt32()); ice_length -= 4; // direction preference candidate.directionPreference = (UInt32)IPAddress.NetworkToHostOrder(reader.ReadInt32()); ice_length -= 4; // other preference candidate.otherPreference = (UInt32)IPAddress.NetworkToHostOrder(reader.ReadInt32()); ice_length -= 4; // tcp type candidate.tcpType = (TcpType)reader.ReadByte(); --ice_length; // ice extension IceExtension iceExtension = new IceExtension(); iceExtension.name = Encoding.UTF8.GetBytes("tcptype"); iceExtension.value = Encoding.UTF8.GetBytes(candidate.tcpType.ToString()); candidate.extension_list.Add(iceExtension); #endregion ice_candidates.Add(candidate); } fSendUpdate = (bool)(reader.ReadByte() == 0 ? false : true); --reload_msg_size; } catch (Exception ex) { throw ex; } return this; }
private static IceCandidate GatherSRSOCandidate(IPAddress localIPAddress) { // local endpoint IPEndPoint localEndpoint = new IPEndPoint(localIPAddress, 0); // listening socket Socket soListeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); soListeningSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); soListeningSocket.Bind(localEndpoint); // update localEndpoint with binded Port localEndpoint = (IPEndPoint)soListeningSocket.LocalEndPoint; // connecting socket Socket soConnectingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); soConnectingSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); soConnectingSocket.Bind(localEndpoint); // STUN1 socket Socket soSTUN1Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); soSTUN1Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); soSTUN1Socket.Bind(localEndpoint); // STUN2 socket Socket soSTUN2Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); soSTUN2Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); soSTUN2Socket.Bind(localEndpoint); // public mapping IPEndPoint publicMapping = null; // get defined STUN servers List<IPEndPoint> definedSTUNServers = GetDefinedSTUNServers(); // no defined STUN servers if (definedSTUNServers.Count == 0) return null; // only one STUN Server defined // so we can't predict the port mapping for two successive outgoing connections // what we can do here is to assume that the outgoing connections get the same port mapping else if (definedSTUNServers.Count == 1) { // try to connect try { soSTUN1Socket.Connect(definedSTUNServers[0]); } catch (Exception e) { //Console.WriteLine(e.Message); // could not connect to STUN server return null; } publicMapping = GetPublicMapping(soSTUN1Socket); } // two STUN servers defined // here we can predict the port mapping for two successive outgoing connections else if (definedSTUNServers.Count == 2) { // try to connect to first STUN server try { // get first public mapping soSTUN1Socket.Connect(definedSTUNServers[0]); IPEndPoint mapping1 = GetPublicMapping(soSTUN1Socket); // now try to connect to second STUN Server try { soSTUN2Socket.Connect(definedSTUNServers[1]); IPEndPoint mapping2 = GetPublicMapping(soSTUN2Socket); // calculate difference between port mappings int portDifference = mapping2.Port - mapping1.Port; // IP will be the same, port will be adapted publicMapping = new IPEndPoint(mapping2.Address, mapping2.Port + portDifference); } catch (Exception e) { //Console.WriteLine(e.Message); // use first mapping and assume port mapping will be equal publicMapping = mapping1; } } catch (Exception e1) { //Console.WriteLine(e1.Message); // could not connect to first STUN server // try second, but then we can't predict port mapping, only assume the port mapping will be equal for next outgoing connection try { soSTUN2Socket.Connect(definedSTUNServers[1]); publicMapping = GetPublicMapping(soSTUN2Socket); } catch (Exception e2) { //Console.WriteLine(e2.Message); // could not connect to first and second STUN Server return null; } } } // got no public mapping if (publicMapping == null) return null; // save data in candidate object IpAddressPort soIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, publicMapping.Address, (ushort)publicMapping.Port); IceCandidate soCandidate = new IceCandidate(soIpAddressPort, Overlay_Link.TLS_TCP_with_FH); soCandidate.cand_type = CandType.tcp_srflx; soCandidate.rel_addr_port = new IpAddressPort(AddressType.IPv4_Address, localEndpoint.Address, (ushort)localEndpoint.Port); soCandidate.soListeningSocket = soListeningSocket; soCandidate.soConnectingSocket = soConnectingSocket; soCandidate.soSTUN1Socket = soSTUN1Socket; soCandidate.soSTUN2Socket = soSTUN2Socket; // TCP Type soCandidate.tcpType = TcpType.SO; // TCP ICE extension IceExtension iceExtension = new IceExtension(); iceExtension.name = Encoding.UTF8.GetBytes("tcptype"); iceExtension.value = Encoding.UTF8.GetBytes("so"); soCandidate.extension_list.Add(iceExtension); return soCandidate; }
private static uint DetermineDirectionPreference(IceCandidate iceCandidate) { // RFC 6544, Section 4.2: /* The direction-pref MUST be between 0 and 7 (both inclusive), with 7 being the most preferred. It is RECOMMENDED that the host, UDP-tunneled, and relayed TCP candidates have the direction-pref assigned as follows: 6 for active, 4 for passive, and 2 for S-O. For the NAT-assisted and server reflexive candidates, the RECOMMENDED values are: 6 for S-O, 4 for active, and 2 for passive. */ // check for TCP extension if (iceCandidate.extension_list != null && iceCandidate.extension_list.Count == 1) { // Host, UDP-tunneled oder Relayed candidate if (iceCandidate.cand_type == CandType.tcp_host || iceCandidate.cand_type == CandType.tcp_udptunneled || iceCandidate.cand_type == CandType.tcp_relay) { switch (Encoding.UTF8.GetString(iceCandidate.extension_list[0].value)) { case "active": return 6; case "passive": return 4; case "so": return 2; } } // NAT-assisted oder Server Reflexive candidate else if (iceCandidate.cand_type == CandType.tcp_nat || iceCandidate.cand_type == CandType.tcp_srflx) { switch (Encoding.UTF8.GetString(iceCandidate.extension_list[0].value)) { case "active": return 4; case "passive": return 2; case "so": return 6; } } // no supported candidate else return 0; } // no TCP extension specified return 0; }
// NAT METHODS private static IceCandidate GatherNAActiveCandidate(IPAddress localIPAddress, IceCandidate baseCandidate) { // exactly the same procedure like GatherSRActiveCandidate() // derived from passive NAT assisted candidate IPEndPoint localEndpoint = new IPEndPoint(localIPAddress, 0); Socket activeConnectingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // here is no bind, because active candidates don't have to be physically allocated here (allocation in connectivity checks) /* RFC 6544 (ICE TCP), Section 3: In the case of active candidates, both IP address and port are present, but the port is meaningless (it is there only for making encoding of active candidates consistent with the other candidate types and is ignored by the peer). As a consequence, active candidates do not need to be physically allocated at the time of address gathering. Rather, the physical allocations, which occur as a consequence of a connection attempt, occur at the time of the connectivity checks. */ // create candidate object IpAddressPort activeIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, baseCandidate.addr_port.ipaddr, 0); // port is meaningless IceCandidate activeCandidate = new IceCandidate(activeIpAddressPort, Overlay_Link.TLS_TCP_with_FH); activeCandidate.cand_type = CandType.tcp_nat; activeCandidate.rel_addr_port = new IpAddressPort(AddressType.IPv4_Address, localEndpoint.Address, 0); // port is meaningless activeCandidate.activeConnectingSocket = activeConnectingSocket; // TCP Type activeCandidate.tcpType = TcpType.Active; // TCP ICE extension IceExtension iceExtension = new IceExtension(); iceExtension.name = Encoding.UTF8.GetBytes("tcptype"); iceExtension.value = Encoding.UTF8.GetBytes("active"); activeCandidate.extension_list.Add(iceExtension); return activeCandidate; }
private static IceCandidate CalculatePriority(IceCandidate iceCandidate) { // set type preference switch (iceCandidate.cand_type) { case CandType.tcp_host: iceCandidate.typePreference = (uint)TypePreference.Host; break; case CandType.tcp_nat: iceCandidate.typePreference = (uint)TypePreference.NATAssisted; break; case CandType.tcp_prflx: iceCandidate.typePreference = (uint)TypePreference.PeerReflexive; break; case CandType.tcp_relay: iceCandidate.typePreference = (uint)TypePreference.Relay; break; case CandType.tcp_srflx: iceCandidate.typePreference = (uint)TypePreference.ServerReflexive; break; case CandType.tcp_udptunneled: iceCandidate.typePreference = (uint)TypePreference.UDPTunneled; break; // no supported candidate type default: return null; } // RFC 6940 (RELOAD), Section 6.5.1.1: // Each ICE candidate is represented as an IceCandidate structure, which is a direct translation of the information from the ICE string // structures, with the exception of the component ID. Since there is only one component, it is always 1, and thus left out of the structure. // component ID : RELOAD specific => always 1 // RFC 6544, Section 4.2: // local preference = (2^13) * direction-pref + other-pref iceCandidate.directionPreference = DetermineDirectionPreference(iceCandidate); // other-pref is set in GatherCandidates() // decremented for each IP Address (or device) // see RFC 6544, Section 4.2: /* If any two candidates have the same type-preference and direction- pref, they MUST have a unique other-pref. With this specification, this usually only happens with multi-homed hosts, in which case other-pref is the preference for the particular IP address from which the candidate was obtained. When there is only a single IP address, this value SHOULD be set to the maximum allowed value (8191). */ // calculate localPreference iceCandidate.localPreference = ((uint)PowerOf2(13)) * iceCandidate.directionPreference + iceCandidate.otherPreference; // calculate priority // RFC 5245, Section 4.1.2.1, formula: // priority = (2^24)*(type preference) + (2^8)*(local preference) + (2^0)*(256 - component ID) iceCandidate.priority = ((uint)PowerOf2(24)) * (iceCandidate.typePreference) + ((uint)PowerOf2(8)) * (iceCandidate.localPreference) + 255; return iceCandidate; }
public IEnumerator<ITask> PreJoinProdecure(List<BootstrapServer> BootstrapServerList) { bool attached = false; ulong bsTransId = 0; if (m_topology.LocalNode.Id == null) yield break; ReloadMessage reloadSendMsg; ReloadMessage reloadRcvMsg = null; /* This is the begin of populating the neighbor table convert local node to resource id + 1 and sent an attach to it */ Destination dest = new Destination(new ResourceId( m_topology.LocalNode.Id + (byte)1)); Destination last_destination = null; Node NextHopNode = null; int succSize = m_ReloadConfig.IamClient ? 1 : ReloadGlobals.SUCCESSOR_CACHE_SIZE; for (int i = 0; i < succSize; i++) { //if (last_destination != null && last_destination == dest) if (last_destination != null && last_destination.Equals(dest)) // markus: we have to use Equals method break; if (m_ReloadConfig.IamClient) reloadSendMsg = create_attach_req(dest, false); else reloadSendMsg = create_attach_req(dest, true); //we do not know the bootstrap peer's node id so far so we leave that parameter empty Node(null) ReloadDialog reloadDialog = null; int RetransmissionTime = ReloadGlobals.RetransmissionTime + ReloadGlobals.MaxTimeToSendPacket; /* Modification for Clients out of draft, TLS stack will take some time * to initialize, add another 10s waiting */ if (m_ReloadConfig.IamClient && i == 0) RetransmissionTime += 10000; int iRetrans = ReloadGlobals.MaxRetransmissions; int iCycleBootstrap = 0; while (iRetrans >= 0 && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown) { /* This is the first bootstrap contacting sequence if NextHopNode * is still zero, in any other case * use an attach to the node where we got the last answer from */ if (NextHopNode == null) { /* we could use a foreach loop, but CCR would multitask it, but we * want serialize that here */ if (iCycleBootstrap >= BootstrapServerList.Count()) iCycleBootstrap = 0; BootstrapServer bss = BootstrapServerList[iCycleBootstrap++]; if (attached == true) break; //TKTODO Rejoin of bootstrap server not solved List<IceCandidate> ics = new List<IceCandidate>(); IceCandidate ice = new IceCandidate(new IpAddressPort( AddressType.IPv4_Address, ReloadGlobals.IPAddressFromHost( m_ReloadConfig, bss.Host), (UInt16)bss.Port), Overlay_Link.TLS_TCP_FH_NO_ICE); // markus: change cand_type to bootstrap ice.cand_type = CandType.tcp_bootstrap; ics.Add(ice); NextHopNode = new Node(reloadRcvMsg == null ? null : reloadRcvMsg.OriginatorID, ics); } try { /* use a new ReloadDialog instance for every usage, Monitor requires it */ reloadDialog = new ReloadDialog(m_ReloadConfig, m_flm, NextHopNode); if (iCycleBootstrap > 0) { // save transaction id from request to bootstrap if (NextHopNode.IceCandidates[0].addr_port.ipaddr.ToString() == BootstrapServerList[iCycleBootstrap - 1].Host && NextHopNode.IceCandidates[0].addr_port.port == BootstrapServerList[iCycleBootstrap - 1].Port) bsTransId = reloadSendMsg.TransactionID; } m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} Dest={2} TransId={3:x16}", RELOAD_MessageCode.Attach_Request.ToString().PadRight(16, ' '), NextHopNode, dest.ToString(), reloadSendMsg.TransactionID)); Arbiter.Activate(m_DispatcherQueue, new IterativeTask<ReloadMessage, ReloadMessageFilter, int>( reloadSendMsg, new ReloadMessageFilter(reloadSendMsg.TransactionID), RetransmissionTime, reloadDialog.Execute)); } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "PreJoinProcedure: " + ex.Message); } yield return Arbiter.Receive(false, reloadDialog.Done, done => { }); if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null) { if (reloadDialog.ReceivedMessage.TransactionID == bsTransId) { if (reloadDialog.ReceivedMessage.forwarding_header.via_list.Count == 1) { BootstrapServer bsServer = BootstrapServerList[iCycleBootstrap - 1]; bsServer.NodeId = reloadDialog.ReceivedMessage.forwarding_header.via_list[0].destination_data.node_id; BootstrapServerList.RemoveAt(iCycleBootstrap - 1); BootstrapServerList.Insert(iCycleBootstrap - 1, bsServer); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("Bootstrap ID: {0}", reloadDialog.ReceivedMessage.forwarding_header.via_list[0].destination_data.node_id)); //Console.WriteLine("Bootstrap ID: {0}", reloadDialog.ReceivedMessage.forwarding_header.via_list[0].destination_data.node_id); } else if (reloadDialog.ReceivedMessage.forwarding_header.via_list.Count == 2) { BootstrapServer bsServer = BootstrapServerList[iCycleBootstrap - 1]; bsServer.NodeId = reloadDialog.ReceivedMessage.forwarding_header.via_list[1].destination_data.node_id; BootstrapServerList.RemoveAt(iCycleBootstrap - 1); BootstrapServerList.Insert(iCycleBootstrap - 1, bsServer); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("Bootstrap ID: {0}", reloadDialog.ReceivedMessage.forwarding_header.via_list[1].destination_data.node_id)); //Console.WriteLine("Bootstrap ID: {0}", reloadDialog.ReceivedMessage.forwarding_header.via_list[1].destination_data.node_id); } bsTransId = 0; } break; } /* still bootstrapping, allow cycling trough different bootstraps by * resetting NextHopNode */ if (i == 0) NextHopNode = null; /* If a response has not been received when the timer fires, the request is retransmitted with the same transaction identifier. */ --iRetrans; if (iRetrans >= 0) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Retrans {0} Attach {1} TransId={2:x16}", iRetrans, NextHopNode, reloadSendMsg.TransactionID)); m_statistics.IncRetransmission(); } else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Failed! Attach {0} TransId={1:x16}", NextHopNode, reloadSendMsg.TransactionID)); m_statistics.IncTransmissionError(); if (ReloadGlobals.AutoExe) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "PreJoin: Exit because initial Attach Faild!"); m_machine.SendCommand("Exit"); } } } try { if (reloadDialog != null && !reloadDialog.Error && reloadDialog.ReceivedMessage != null) { //the SourceNodeID delivered from reloadDialog comes from connection table and is the last hop of the message reloadRcvMsg = reloadDialog.ReceivedMessage; RELOAD_MessageCode msgCode = reloadRcvMsg.reload_message_body.RELOAD_MsgCode; if (reloadRcvMsg != null) { if (msgCode == RELOAD_MessageCode.Attach_Answer) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} <== {1} last={2} TransId={3:x16}", msgCode.ToString().PadRight(16, ' '), reloadRcvMsg.OriginatorID, reloadRcvMsg.LastHopNodeId, reloadRcvMsg.TransactionID)); AttachReqAns answ = (AttachReqAns)reloadRcvMsg.reload_message_body; if (answ != null) { m_ReloadConfig.State = ReloadConfig.RELOAD_State.PreJoin; m_machine.StateUpdates(ReloadConfig.RELOAD_State.PreJoin); /* An Attach in and of itself does not result in updating the routing * table of either node. * Note: We use the routing table here only for storing ice candidates * for later use, we will not update successor or predecessor list */ NextHopNode = new Node(reloadRcvMsg.OriginatorID, answ.ice_candidates); /* An Attach in and of itself does not result in updating the routing * table of either node. * Note: We use the routing table here only for storing ice candidates * for later use, we will not update successor or predecessor list */ m_topology.routing_table.AddNode(NextHopNode); m_topology.routing_table.SetNodeState(NextHopNode.Id, NodeState.attached); if (CheckAndSetAdmittingPeer(NextHopNode) && NextHopNode.Id != reloadRcvMsg.LastHopNodeId) // Send ping to establish a physical connection Arbiter.Activate(m_DispatcherQueue, new IterativeTask<Destination, PingOption>(new Destination( NextHopNode.Id), PingOption.direct, SendPing)); if (m_ReloadConfig.IamClient) { m_ReloadConfig.LastJoinedTime = DateTime2.Now; TimeSpan joiningTime = m_ReloadConfig.LastJoinedTime - m_ReloadConfig.StartJoinMobile; m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_MEASURE, "Join:" + joiningTime.TotalSeconds.ToString()); } attached = true; } } else if (msgCode == RELOAD_MessageCode.Error) { if (dest.type == DestinationType.node) { ErrorResponse error = (ErrorResponse)reloadRcvMsg.reload_message_body; if (error != null) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Prejoin: Got Error {0} from {1} deleting {2}", error.ErrorMsg, reloadRcvMsg.OriginatorID, dest.destination_data.node_id)); m_topology.routing_table.Leave(dest.destination_data.node_id); } } } } else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "PreJoinProcedure: reloadRcvMsg == null!!"); } last_destination = dest; dest = new Destination(new ResourceId(reloadRcvMsg.OriginatorID) + (byte)1); } else break; } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "PreJoinProcedure: " + ex.Message); } } // End Successor Search // FingerTable enrichment if (!m_ReloadConfig.IamClient) { List<FTEntry> fingers = m_topology.routing_table.AttachFingers(); Port<bool> attachNextPort = null; Boolean attachNext = true; /* JP SHOULD send Attach requests to initiate connections to each of * the peers in the neighbor table as well as to the desired finger * table entries. */ foreach (FTEntry finger in fingers) { attachNextPort = new Port<bool>(); Arbiter.Activate(m_DispatcherQueue, new IterativeTask<FTEntry, Port<bool>>( finger, attachNextPort, AttachFinger)); /* Wait for finger attach */ yield return Arbiter.Receive(false, attachNextPort, next => { attachNext = next; }); if (!attachNext) break; } } /* see base -18 p.106 /* 4. JP MUST enter all the peers it has contacted into its routing /* table. */ m_topology.routing_table.Conn2Route(); /* Once JP has a reasonable set of connections it is ready to take its * place in the DHT. It does this by sending a Join to AP. */ if (m_ReloadConfig.AdmittingPeer != null) if (!m_ReloadConfig.IamClient) { m_ReloadConfig.State = ReloadConfig.RELOAD_State.Joining; m_machine.StateUpdates(ReloadConfig.RELOAD_State.Joining); m_topology.routing_table.SetWaitForJoinAnsw( m_ReloadConfig.AdmittingPeer.Id, true); reloadSendMsg = create_join_req( new Destination(m_ReloadConfig.AdmittingPeer.Id)); ReloadDialog reloadDialog = null; int RetransmissionTime = ReloadGlobals.RetransmissionTime + ReloadGlobals.MaxTimeToSendPacket; int iRetrans = ReloadGlobals.MaxRetransmissions; while (iRetrans >= 0 && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown) { reloadDialog = new ReloadDialog(m_ReloadConfig, m_flm, m_ReloadConfig.AdmittingPeer); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} TransId={2:x16}", RELOAD_MessageCode.Join_Request.ToString().PadRight(16, ' '), m_ReloadConfig.AdmittingPeer, reloadSendMsg.TransactionID)); Arbiter.Activate(m_DispatcherQueue, new IterativeTask<ReloadMessage, ReloadMessageFilter, int>(reloadSendMsg, new ReloadMessageFilter(reloadSendMsg.TransactionID), RetransmissionTime, reloadDialog.Execute)); yield return Arbiter.Receive(false, reloadDialog.Done, done => { }); if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null) break; /* If a response has not been received when the timer fires, the request is retransmitted with the same transaction identifier. */ --iRetrans; if (iRetrans >= 0) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Retrans {0} Join {1} TransId={2:x16}", iRetrans, m_ReloadConfig.AdmittingPeer, reloadSendMsg.TransactionID)); m_statistics.IncRetransmission(); } else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Failed! Join {0} TransId={1:x16}", m_ReloadConfig.AdmittingPeer, reloadSendMsg.TransactionID)); m_statistics.IncTransmissionError(); } } try { if (!reloadDialog.Error) { reloadRcvMsg = reloadDialog.ReceivedMessage; RELOAD_MessageCode msgCode = reloadRcvMsg.reload_message_body.RELOAD_MsgCode; if (reloadRcvMsg != null) { if (msgCode == RELOAD_MessageCode.Join_Answer) { m_topology.routing_table.SetWaitForJoinAnsw(reloadRcvMsg.OriginatorID, false); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} <== {1} TransId={2:x16}", msgCode.ToString().PadRight(16, ' '), reloadRcvMsg.OriginatorID, reloadRcvMsg.TransactionID)); NodeState nodestate = m_topology.routing_table.GetNodeState(reloadRcvMsg.OriginatorID); if (nodestate == NodeState.updates_received) { /* we previously received an update from admitting peer (maybe * race condition), now joining is complete in any other case * wait for updates to come from this node */ m_ReloadConfig.State = ReloadConfig.RELOAD_State.Joined; m_machine.StateUpdates(ReloadConfig.RELOAD_State.Joined); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("Joining completed")); m_ReloadConfig.LastJoinedTime = DateTime.Now; TimeSpan joiningTime = m_ReloadConfig.LastJoinedTime - m_ReloadConfig.StartJoining; m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_MEASURE, String.Format("Join:{0}", joiningTime.TotalSeconds.ToString())); m_topology.routing_table.SendUpdateToAllNeighbors(); } else { m_ReloadConfig.LastJoinedTime = DateTime.Now; TimeSpan joiningTime = m_ReloadConfig.LastJoinedTime - m_ReloadConfig.StartTime; m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_MEASURE, String.Format("Join:{0}", joiningTime.TotalSeconds.ToString())); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Prejoin: nodestate != update_recv at Node {0}", m_machine.ReloadConfig.ListenPort)); } //m_topology.routing_table.SendUpdatesToAllFingers(); } } else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "PreJoinProcedure: reloadRcvMsg == null!!"); } } } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "PreJoinProcedure: " + ex.Message); } } else { if (m_ReloadConfig.SipUri == "") m_ReloadConfig.SipUri = String.Format("{0}@{1}", ReloadGlobals.HostName, m_ReloadConfig.OverlayName); if (m_ReloadConfig.SipUri != null && m_ReloadConfig.SipUri != "") { // explictite SIP registration as minimal config for RELOAD clients IUsage sipRegistration = m_machine.UsageManager.CreateUsage(Usage_Code_Point.SIP_REGISTRATION, 2, m_ReloadConfig.SipUri); sipRegistration.ResourceName = m_ReloadConfig.SipUri; List<StoreKindData> clientRegistrationList = new List<StoreKindData>(); StoreKindData sipKindData = new StoreKindData(sipRegistration.KindId, 0, new StoredData(sipRegistration.Encapsulate(true))); clientRegistrationList.Add(sipKindData); Arbiter.Activate(m_DispatcherQueue, new IterativeTask<string, List<StoreKindData>>(m_ReloadConfig.SipUri, clientRegistrationList, Store)); } } else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_MEASURE, String.Format("PreJoinPredure => Node {0} has no admitting peer = {1}!", m_machine.ReloadConfig.ListenPort, m_ReloadConfig.AdmittingPeer)); if (ReloadGlobals.AutoExe) { m_machine.SendCommand("Exit"); } } } // End PreJoin
public bool EqualsInAddressPort(IceCandidate iceCandidate) { // check if IP Address and Port are equal if (this.addr_port.ipaddr.Equals(iceCandidate.addr_port.ipaddr) && this.addr_port.port == iceCandidate.addr_port.port && this.addr_port.type == iceCandidate.addr_port.type) { return true; } else return false; }