/// <summary> /// If the tunnel is connected, a new AnpTransport is created and the /// method returns true. Otherwise, the method returns false. /// </summary> public bool CheckConnect() { SelectSockets select = new SelectSockets(); select.Timeout = 0; select.AddRead(tunnel.Sock); tunnel.CheckTls(); select.Select(); if (select.ReadSockets.Contains(tunnel.Sock)) { CreateTransport(); return true; } return false; }
/// <summary> /// Start kmod and connect to it. /// </summary> private void StartKmod() { FileStream file = null; Socket listenSock = null; RegistryKey kwmRegKey = null; try { // Get the path to the kmod executable in the registry. kwmRegKey = KwmReg.GetKwmLMRegKey(); String Kmod = "\"" + (String)kwmRegKey.GetValue("InstallDir", @"C:\Program Files\Teambox\Teambox Manager") + "\\kmod\\kmod.exe\""; // The directory where KMOD will save logs and its database for use with the kwm. String KmodDir = KwmPath.GetKmodDirPath(); Directory.CreateDirectory(KmodDir); // Start listening for kmod to connect when it'll be started. IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, 0); listenSock = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); listenSock.Bind(endPoint); listenSock.Listen(1); int port = ((IPEndPoint)listenSock.LocalEndPoint).Port; // Start KMOD in debugging mode if our settings say so. String debug = KwmCfg.Cur.KtlstunnelLoggingLevel > 0 ? " -l 3" : ""; String args = " -C kmod_connect -p " + port + debug + " -m 20000 -k \"" + KmodDir + "\""; String cmdLine = Kmod + args; KLogging.Log("About to start kmod.exe: " + cmdLine); m_kmodProc = new KProcess(cmdLine); m_kmodProc.InheritHandles = false; m_kmodProc.CreationFlags = (uint)KSyscalls.CREATION_FLAGS.CREATE_NO_WINDOW; m_kmodProc.Start(); // Wait for KMOD to connect for about 10 seconds. DateTime startTime = DateTime.Now; while (true) { SelectSockets select = new SelectSockets(); select.AddRead(listenSock); SetSelectTimeout(startTime, 10000, select, "no KMOD connection received"); Block(select); if (select.InRead(listenSock)) { m_kmodSock = listenSock.Accept(); m_kmodSock.Blocking = false; break; } } // Read the authentication data. byte[] authSockData = new byte[32]; byte[] authFileData = new byte[32]; startTime = DateTime.Now; int nbRead = 0; while (nbRead != 32) { SelectSockets select = new SelectSockets(); select.AddRead(m_kmodSock); SetSelectTimeout(startTime, 2000, select, "no authentication data received"); Block(select); int r = KSocket.SockRead(m_kmodSock, authSockData, nbRead, 32 - nbRead); if (r > 0) nbRead += r; } file = File.Open(KmodDir + "\\connect_secret", FileMode.Open); file.Read(authFileData, 0, 32); if (!KUtil.ByteArrayEqual(authFileData, authSockData)) throw new Exception("invalid authentication data received"); // Set the transport. m_transport = new K3pTransport(m_kmodSock); } finally { if (file != null) file.Close(); if (listenSock != null) listenSock.Close(); if (kwmRegKey != null) kwmRegKey.Close(); } }
/// <summary> /// Run one pass of the main loop. /// </summary> private void RunPass() { // Wait for a command. while (m_commandQueue.Count == 0) Block(new SelectSockets()); // Get the next command. KmodThreadCommand command = m_commandQueue.Dequeue(); // Send the command. m_transport.sendMsg(command.Msg); while (true) { m_transport.doXfer(); if (!m_transport.isSending) break; SelectSockets select = new SelectSockets(); select.AddWrite(m_kmodSock); Block(select); } // We're done. if (!command.HaveResultFlag) return; // Wait for the results or the next command. bool firstFlag = true; while (m_commandQueue.Count == 0) { if (!m_transport.isReceiving) m_transport.beginRecv(); m_transport.doXfer(); // Push the next result. if (m_transport.doneReceiving) { lock (Mon) { m_elementQueue.Enqueue(m_transport.getRecv()); Monitor.Pulse(Mon); } // Send the notification that results are ready for this command. if (firstFlag) { firstFlag = false; PostToUI(new KmodThreadNotif(m_broker, command)); } } // Wait for the next result or the next command. else { SelectSockets select = new SelectSockets(); select.AddRead(m_kmodSock); Block(select); } } }
public override void BeforeSelectHandshake(SelectSockets selectSockets) { double timeout = GetHandshakeTimeout(); if (timeout <= 0) throw new Exception("timeout waiting for client authentication data"); selectSockets.AddRead(Sock); selectSockets.LowerTimeout((int)timeout); }
protected override void RunPass() { SelectSockets selectSockets = new SelectSockets(); SortedDictionary<UInt64, EAnpServerThreadChannel> tree = new SortedDictionary<UInt64, EAnpServerThreadChannel>(ChannelTree); // Dispatch before the call to select(). selectSockets.AddRead(ListenSock); foreach (EAnpThreadChannel c in tree.Values) c.BeforeSelect(selectSockets); // Block. Block(selectSockets); // Dispatch after the call to select(). foreach (EAnpThreadChannel c in tree.Values) c.AfterSelect(selectSockets); AfterSelectListen(selectSockets); }
/// <summary> /// Update the select set specified with the socket of the transport. /// </summary> public void UpdateSelect(SelectSockets selectSocket) { Debug.Assert(IsReceiving || DoneReceiving); if (IsSending) selectSocket.AddWrite(sock); if (IsReceiving && !DoneReceiving) selectSocket.AddRead(sock); }
/// <summary> /// Wait for one of the sockets specified to become ready, for a message /// to arrive or for the thread to be cancelled. Be careful not to call /// Block() while handling a message, since this method does not handle /// recursivity. Do not call this method after it has thrown an exception. /// </summary> protected void Block(SelectSockets set) { Debug.Assert(!BlockedFlag); BlockedFlag = true; set.AddRead(SocketPair[1]); set.Select(); FlushWakeUp(); CheckCancellation(); CheckMessages(); BlockedFlag = false; }
protected override void Run() { // Connect the tunnel. InternalAnpTunnel = new AnpTunnel(Host, Port); Tunnel tunnel = InternalAnpTunnel.GetTunnel(); InternalAnpTunnel.BeginConnect(ReconnectHost, ReconnectPort); while (true) { SelectSockets set = new SelectSockets(); set.Timeout = 100; tunnel.CheckTls(); set.AddRead(tunnel.Sock); Block(set); if (set.ReadSockets.Contains(tunnel.Sock)) { InternalAnpTunnel.CreateTransport(); break; } } // Handle the tunnel. OnTunnelConnected(); }