private void c_OnDisconnect(ClientStream s) { try { lock (sync) { if (connectedClientNodes.Contains(s)) { //Check it is actually the same node // var search = connectedClientNodes.Where(n => n.Node.ID == s.Node.ID && s.Node.Secret == s.Node.Secret).FirstOrDefault(); // if (null == search) { logger.Debug("Server dropped client {0}", s.Node.ID); connectedClientNodes.Remove(s); s.OnDisconnect -= c_OnDisconnect; var info = new UpdateVerb(); info.Nodes.Add(new Node {ID = s.Node.ID, Online = false}); NetworkRequest req = info.CreateRequest(); req.OverlordID = serverNode.ID; req.SourceID = serverNode.ID; SendToOverlordClients(req); SendToStandardClients(req); } } } } catch { } }
private bool HandleConnect(NetworkRequest r, RequestEventArgs e) { string address = string.Empty; try { var iv = new ConnectVerb(); iv.ProcessRequest(r); address = iv.Address; if (string.IsNullOrEmpty(iv.Secret)) { //Dont allow connections with no secret return false; } //Dont allow connections to ourselves.. if (iv.Address == serverNode.Location) return false; //Only allow one connect attempt at once lock (sync) { if (connectingIDs.Contains(address)) return false; connectingIDs.Add(address); } //Connect to the remote client var verb = new InfoVerb(); var client = new Client(serverNode); if (!client.Execute(verb, address)) return false; //Connected ok var c = new ClientStream(); c.OnDisconnect += c_OnDisconnect; Node n = verb.GetValidatedNode(); if (null == n) return false; n.Location = iv.Address; n.Online = true; n.NodeType = iv.ClientType; n.OverlordID = serverNode.ID; n.Secret = iv.Secret; lock (sync) { //Notify other clients var update = new UpdateVerb(); //Was this person already connected? ClientStream search = connectedClientNodes.Where(xn => xn.Node.ID == n.ID).FirstOrDefault(); if (null != search) { connectedClientNodes.Remove(search); search.Kill(); } c.Start(n, serverNode); connectedClientNodes.Add(c); update.Nodes.Add(n); NetworkRequest req = update.CreateRequest(); req.SourceID = serverNode.ID; req.OverlordID = serverNode.ID; req.AuthKey = iv.Secret; SendToStandardClients(req); //Dont send overlord logs to other overlords if (n.NodeType != ClientType.Overlord) SendToOverlordClients(req); } //Find client servers ThreadPool.QueueUserWorkItem(ScanClientAsync, n); //return ok //Add headers var headers = e.Response.Headers as HeaderCollection; if (null != headers) { headers.Add("FAP-AUTH", iv.Secret); headers.Add("FAP-SOURCE", serverNode.ID); headers.Add("FAP-OVERLORD", serverNode.ID); } SendResponse(e, null); //Send network info if (n.NodeType == ClientType.Overlord) { var update = new UpdateVerb(); //Only send local nodes foreach ( ClientStream peer in connectedClientNodes.ToList().Where(x => x.Node.NodeType == ClientType.Client)) update.Nodes.Add(peer.Node); NetworkRequest req = update.CreateRequest(); req.SourceID = serverNode.ID; req.OverlordID = serverNode.ID; req.AuthKey = iv.Secret; c.AddMessage(req); } else { var update = new UpdateVerb(); //None overlord client. Send local nodes and external ones. update.Nodes = GetBestKnownClientList(); NetworkRequest req = update.CreateRequest(); req.SourceID = serverNode.ID; req.OverlordID = serverNode.ID; req.AuthKey = iv.Secret; c.AddMessage(req); } return true; } catch { } finally { connectingIDs.Remove(address); } SendError(e); return false; }