public bool Verify(X509Certificate certificate, ISender sender) { Address addr = null; AHSender ahsender = sender as AHSender; if (ahsender != null) { addr = ahsender.Destination; } else { Edge edge = sender as Edge; if (edge != null) { Connection con = _ct.GetConnection(edge); if (con != null) { addr = con.Address; } } } if (addr == null) { return(true); } return(CertificateHandler.Verify(certificate, addr.ToString())); }
/** * Handle the notification that the other side is going to close the edge */ public IDictionary Close(IDictionary close_message, ISender edge) { Edge from = GetEdge(edge); ConnectionTable tab = _node.ConnectionTable; /** * In order to make sure that we close gracefully, we simply * move this edge to the unconnected list. The node will * close edges that have been there for some time */ Connection c = tab.GetConnection(from); if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "sys:link.Close on {0} connection: {1}", from, c)); } tab.Disconnect(from); /** * Release locks when the close message arrives; do not wait * until the edge actually closes. */ CloseHandler(from, null); if (ProtocolLog.EdgeClose.Enabled) { String reason = String.Empty; if (close_message.Contains(reason)) { reason = (String)close_message["reason"]; } ProtocolLog.Write(ProtocolLog.EdgeClose, String.Format( "sys:link.Close - " + from + ": " + reason)); } /** * Try to close the edge after a small time span: */ Brunet.Util.FuzzyTimer.Instance.DoAfter(delegate(DateTime now) { _node.EnqueueAction(new Node.GracefulCloseAction(_node, from, "CPH, delayed close")); }, 5000, 1000); return(new ListDictionary()); }
/** * Get a StatusMessage for this node */ public IDictionary GetStatus(IDictionary status_message, ISender edge) { //we just got s status request if (1 == _disconnecting) { throw new AdrException((int)ErrorMessage.ErrorCode.Disconnecting, "disconnecting"); } StatusMessage sm = new StatusMessage(status_message); Edge from = GetEdge(edge); if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "{0} -start- sys:link.GetStatus({1},{2})", _node.Address, sm, edge)); } CphState cphstate = null; if (from != null) { cphstate = _edge_to_cphstate[from] as CphState; } /** * StatusMessage objects are used to verify the completion * of the Link protocol. If we receive a StatusMessage request * after we send a LinkMessage response, we know the other * Node got our LinkMessage response, and the connection * is active */ StatusMessage response = null; ConnectionTable tab = _node.ConnectionTable; if (cphstate != null) { try { LinkMessage lm_to_add = cphstate.LM; //This is part of connection process: response = _node.GetStatus(sm.NeighborType, lm_to_add.Local.Address); Connection con = new Connection(from, lm_to_add.Local.Address, lm_to_add.ConTypeString, sm, lm_to_add); tab.Add(con); } finally { from.CloseEvent -= this.CloseHandler; CloseHandler(from, null); } } else { //This is just a "regular" status request //update our table: Address fadd = null; Connection c = tab.GetConnection(from); if (c != null) { fadd = c.Address; tab.UpdateStatus(c, sm); } response = _node.GetStatus(sm.NeighborType, fadd); } if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "{0} -end- sys:link.GetStatus()->{1}", _node.Address, response)); } return(response.ToDictionary()); }
/** * This starts a linking operation on the given edge */ public IDictionary Start(IDictionary link_message, ISender edge) { if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "{0} -start- sys:link.Start", _node.Address)); } Edge from = GetEdge(edge); LinkMessage lm = new LinkMessage(link_message); if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "{0} -args- sys:link.Start({1},{2})", _node.Address, lm, from)); } CphState cph = new CphState(from, lm); lock ( _sync ) { if (!_edge_to_cphstate.ContainsKey(from)) { _edge_to_cphstate[from] = cph; } else { throw new AdrException((int)ErrorMessage.ErrorCode.InProgress, "Already have a link in progress on this edge"); } } ErrorMessage err = null; if (CanConnect(cph, out err)) { try { //If the CloseEvent was already called, this throws an exception from.CloseEvent += this.CloseHandler; } catch { CloseHandler(from, null); throw new AdrException((int)ErrorMessage.ErrorCode.EdgeClosed, "Edge Closed after receiving message"); } } else { lock ( _sync ) { _edge_to_cphstate.Remove(from); } } //Now we prepare our response LinkMessage lm_resp = null; if (err == null) { //We send a response: NodeInfo n_info = NodeInfo.CreateInstance(_node.Address, from.LocalTA); NodeInfo remote_info = NodeInfo.CreateInstance(null, from.RemoteTA); System.Collections.Specialized.StringDictionary attrs = new System.Collections.Specialized.StringDictionary(); attrs["type"] = String.Intern(lm.ConTypeString); attrs["realm"] = String.Intern(_node.Realm); lm_resp = new LinkMessage(attrs, n_info, remote_info, lm.Token); } else { if (err.Ec == ErrorMessage.ErrorCode.AlreadyConnected) { /** * When we send the ErrorCode.AlreadyConnected, * we could have a stale connection, lets try pinging * the other node, if they are there, but have lost * the Edge, this may trigger the edge to close, causing * us to remove the Connection. * @todo consider putting this address on a "fast track" * to removal if we don't hear from it soon */ ConnectionTable tab = _node.ConnectionTable; Connection c = tab.GetConnection(lm.ConnectionType, lm.Local.Address); if (c != null) { RpcManager rpc = _node.Rpc; rpc.Invoke(c.Edge, null, "sys:link.Ping", String.Empty); } } } if (err != null) { throw new AdrException((int)err.Ec, err.Message); } if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "{0} -end- sys:link.Start()->{1}", _node.Address, lm_resp)); } return(lm_resp.ToDictionary()); }