public void SaveConnection(CandidatePair choosenPair) { // get connection socket to remote peer switch (choosenPair.localCandidate.tcpType) { case TcpType.Active: { if (choosenPair.localCandidate.activeConnectingSocket.Connected) m_connectionsToRemotePeer.Add(choosenPair.remoteCandidate.addr_port, choosenPair.localCandidate.activeConnectingSocket); } break; case TcpType.Passive: { if (choosenPair.localCandidate.passiveAcceptedSocket.Connected) m_connectionsToRemotePeer.Add(choosenPair.remoteCandidate.addr_port, choosenPair.localCandidate.passiveAcceptedSocket); } break; case TcpType.SO: { if (choosenPair.localCandidate.soConnectingSocket.Connected) m_connectionsToRemotePeer.Add(choosenPair.remoteCandidate.addr_port, choosenPair.localCandidate.soConnectingSocket); else if (choosenPair.localCandidate.soAcceptedSocket.Connected) m_connectionsToRemotePeer.Add(choosenPair.remoteCandidate.addr_port, choosenPair.localCandidate.soAcceptedSocket); } break; } // switch }
public Socket GetConnection(CandidatePair choosenPair) { // get connection socket to remote peer switch (choosenPair.localCandidate.tcpType) { case TcpType.Active: { if (choosenPair.localCandidate.activeConnectingSocket.Connected) return choosenPair.localCandidate.activeConnectingSocket; } break; case TcpType.Passive: { if (choosenPair.localCandidate.passiveAcceptedSocket.Connected) return choosenPair.localCandidate.passiveAcceptedSocket; } break; case TcpType.SO: { if (choosenPair.localCandidate.soConnectingSocket.Connected) return choosenPair.localCandidate.soConnectingSocket; else if (choosenPair.localCandidate.soAcceptedSocket.Connected) return choosenPair.localCandidate.soAcceptedSocket; } break; } // switch return null; }
private static Socket RunAcceptAndConnect(CandidatePair candPair, Socket connectingSocket, Socket listeningSocket) { // Connect() and Accept() must run simultaneously => use Threads Socket acceptedSocket = null; Thread acceptThread = new Thread(() => { acceptedSocket = TimeoutSocket.Accept(listeningSocket, ICE.SOCKET_TIMEOUT); }); Thread connectThread = new Thread(() => { TimeoutSocket.Connect(connectingSocket, new IPEndPoint(candPair.remoteCandidate.addr_port.ipaddr, candPair.remoteCandidate.addr_port.port), ICE.SOCKET_TIMEOUT); }); acceptThread.Start(); connectThread.Start(); acceptThread.Join(); connectThread.Join(); return acceptedSocket; }
//public static void PrintCandidateList(List<IceCandidate> list) //{ // foreach (IceCandidate cand in list) // PrintCandidate(cand); // Console.WriteLine("==================================================="); //} public static void PrintCandidatePair(CandidatePair candidatePair) { // mapping string local = candidatePair.localCandidate.addr_port.ipaddr.ToString() + ":" + candidatePair.localCandidate.addr_port.port + " (" + candidatePair.localCandidate.tcpType.ToString() + " / " + candidatePair.localCandidate.cand_type.ToString() + ")"; Console.WriteLine(local.PadRight(50, '.') + "{0}:{1} ({2} / {3})", candidatePair.remoteCandidate.addr_port.ipaddr.ToString(), candidatePair.remoteCandidate.addr_port.port, candidatePair.remoteCandidate.tcpType.ToString(), candidatePair.remoteCandidate.cand_type.ToString()); // candidates have a base? (means no host) if (candidatePair.localCandidate.rel_addr_port != null && candidatePair.remoteCandidate.rel_addr_port != null) { string localBase = "Base: " + candidatePair.localCandidate.rel_addr_port.ipaddr.ToString() + ":" + candidatePair.localCandidate.rel_addr_port.port; Console.WriteLine(localBase.PadRight(50) + "Base: {0}:{1}", candidatePair.remoteCandidate.rel_addr_port.ipaddr.ToString(), candidatePair.remoteCandidate.rel_addr_port.port); } else if (candidatePair.localCandidate.rel_addr_port != null && candidatePair.remoteCandidate.rel_addr_port == null) { Console.WriteLine("Base: " + candidatePair.localCandidate.rel_addr_port.ipaddr.ToString() + ":" + candidatePair.localCandidate.rel_addr_port.port); } else if (candidatePair.localCandidate.rel_addr_port == null && candidatePair.remoteCandidate.rel_addr_port != null) { Console.WriteLine("".PadRight(50) + "Base: {0}:{1}", candidatePair.remoteCandidate.rel_addr_port.ipaddr.ToString(), candidatePair.remoteCandidate.rel_addr_port.port); } }
private static void PeformCheck(CandidatePair candPair, ReloadConfig.LogHandler logger) { // local active candidate if (candPair.localCandidate.tcpType == TcpType.Active) { // try to connect to remote candidate try { //Socket connectingSocket = candPair.localCandidate.activeConnectingSocket; IPEndPoint localEndPoint = new IPEndPoint(candPair.localCandidate.addr_port.ipaddr, candPair.localCandidate.addr_port.port); Socket connectingSocket = null; int retry = CONNECT_RETRIES; while (retry > 0) { logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("PerformCheck connect to {0}:{1} retry {2}", candPair.remoteCandidate.addr_port.ipaddr.ToString(), candPair.remoteCandidate.addr_port.port, retry)); connectingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); connectingSocket.Bind(localEndPoint); TimeoutSocket.Connect(connectingSocket, new IPEndPoint(candPair.remoteCandidate.addr_port.ipaddr, candPair.remoteCandidate.addr_port.port), ICE.SOCKET_TIMEOUT / CONNECT_RETRIES); if (connectingSocket.Connected) break; retry--; } // connected? if (connectingSocket.Connected) { // TEST: save connected socket candPair.localCandidate.activeConnectingSocket = connectingSocket; // TODO: send stun checks // if stun check is successfull set state to succeeded candPair.state = CandidatePairState.Succeeded; } else { candPair.state = CandidatePairState.Failed; } } catch (Exception e) { //Console.WriteLine(e.Message); /* RFC 6544, ICE-TCP, Section 7.1: If the TCP connection cannot be established, the check is considered to have failed, and a full-mode agent MUST update the pair state to Failed in the check list */ candPair.state = CandidatePairState.Failed; } } // local passive candidate else if (candPair.localCandidate.tcpType == TcpType.Passive) { // try to accept a connection on listening port from remote peer try { Socket listeningSocket = candPair.localCandidate.passiveListeningSocket; listeningSocket.Listen(10); logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("PerformCheck listen to {0}:{1}", ((IPEndPoint)listeningSocket.LocalEndPoint).Address.ToString(), ((IPEndPoint)listeningSocket.LocalEndPoint).Port)); //Socket acceptedSocket = candPair.localCandidate.passiveAcceptedSocket; candPair.localCandidate.passiveAcceptedSocket = TimeoutSocket.Accept(listeningSocket, ICE.SOCKET_TIMEOUT); // connection accepted? if (candPair.localCandidate.passiveAcceptedSocket != null && candPair.localCandidate.passiveAcceptedSocket.Connected) { // TODO: send stun checks // if stun check is successfull set state to succeeded candPair.state = CandidatePairState.Succeeded; } else { candPair.state = CandidatePairState.Failed; } } catch (Exception e) { candPair.state = CandidatePairState.Failed; } } // local so candidate else if (candPair.localCandidate.tcpType == TcpType.SO) { // try to connect to remote candidate and to accept a connection on listening port from remote peer try { Socket connectingSocket = candPair.localCandidate.soConnectingSocket; Socket listeningSocket = candPair.localCandidate.soListeningSocket; listeningSocket.Listen(10); // run Accept and Connect simultaneously Socket acceptedSocket = candPair.localCandidate.soAcceptedSocket; candPair.localCandidate.soAcceptedSocket = RunAcceptAndConnect(candPair, connectingSocket, listeningSocket); if (connectingSocket.Connected || (acceptedSocket != null && acceptedSocket.Connected)) { // TODO: send stun checks // if stun check is successfull set state to succeeded candPair.state = CandidatePairState.Succeeded; } else { candPair.state = CandidatePairState.Failed; } } catch (Exception e) { candPair.state = CandidatePairState.Failed; } } }
public bool EqualsInAddressPort(CandidatePair candidatePair) { // checks if the IP Address and the Port of the local and the remote candidate are equal if (this.localCandidate.EqualsInAddressPort(candidatePair.localCandidate) && this.remoteCandidate.EqualsInAddressPort(candidatePair.remoteCandidate)) { return true; } else return false; }
private static List<CandidatePair> FormingCandidatePairs(List<IceCandidate> localCandidates, List<IceCandidate> remoteCandidates) // checked { List<CandidatePair> candidatePairs = new List<CandidatePair>(); /* RFC 6544, ICE-TCP, Section 6.2: Local Remote Candidate Candidate --------------------------- tcp-so tcp-so tcp-active tcp-passive tcp-passive tcp-active */ foreach (IceCandidate localCandidate in localCandidates) { foreach (IceCandidate remoteCandidate in remoteCandidates) { // in RELOAD there is no component ID in the ICE structure, since there is // only one component, it is always 1, and thus left out of the structure. // so we only have to check if both candidates have the same IP address version if (localCandidate.addr_port.type == remoteCandidate.addr_port.type) { if (localCandidate.tcpType == TcpType.Active && remoteCandidate.tcpType == TcpType.Passive) { CandidatePair candidatePair = new CandidatePair(localCandidate, remoteCandidate); candidatePairs.Add(candidatePair); } else if (localCandidate.tcpType == TcpType.Passive && remoteCandidate.tcpType == TcpType.Active) { CandidatePair candidatePair = new CandidatePair(localCandidate, remoteCandidate); candidatePairs.Add(candidatePair); } else if (localCandidate.tcpType == TcpType.SO && remoteCandidate.tcpType == TcpType.SO) { CandidatePair candidatePair = new CandidatePair(localCandidate, remoteCandidate); candidatePairs.Add(candidatePair); } } } } //PrintCandidatePairList(candidatePairs); if (candidatePairs.Count > 0) return candidatePairs; else return null; }
public Socket GetConnection(CandidatePair choosenPair) { throw new NotImplementedException(); }
public void SaveConnection(CandidatePair choosenPair) { }