Пример #1
0
        /// <summary>3a) Receive a DHEWithCertificate, verify the certificate and DHE and
        /// send a Confirm that you are ready to Verify the stack and start the
        /// system.</summary>
        /// <param name="sa">A security association that we wish to perform the
        /// specified control operation on.</param>
        /// <param name="scm">The received SecurityControlMessage.</param>
        /// <param name="scm_reply">A prepared reply message (with headers and such.</param>
        /// <param name="return_path">Where to send the result.</param>
        /// <param name="low_level_sender">We expect the return_path to not be an edge or
        /// some other type of "low level" sender, so this contains the parsed out value.</param>
        protected void HandleControlDHEWithCertificate(PeerSecAssociation sa,
                                                       SecurityControlMessage scm, SecurityControlMessage scm_reply,
                                                       ISender return_path, ISender low_level_sender)
        {
            ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Received DHEWithCertificate from: " + low_level_sender);
            if (sa == null)
            {
                throw new Exception("No valid SA!");
            }
            byte[] cert = new byte[scm.Certificate.Length];
            scm.Certificate.CopyTo(cert, 0);
            X509Certificate rcert = new X509Certificate(cert);
            HashAlgorithm   sha1  = new SHA1CryptoServiceProvider();

            scm.Verify((RSACryptoServiceProvider)rcert.RSA, sha1);
            _ch.Verify(rcert, low_level_sender);

            sa.RemoteCertificate = rcert;
            sa.RDHE.Value        = scm.DHE;

            scm_reply.LocalCookie  = scm.RemoteCookie;
            scm_reply.RemoteCookie = scm.LocalCookie;
            scm_reply.Hash         = MemBlock.Reference(sha1.ComputeHash((byte[])scm.Packet));
            scm_reply.Type         = SecurityControlMessage.MessageType.Confirm;
            lock (_private_key_lock) {
                scm_reply.Sign(_private_key, sha1);
            }

            ICopyable to_send = new CopyList(Security, SecureControl, scm_reply.Packet);

            _rrman.SendRequest(return_path, ReqrepManager.ReqrepType.Request,
                               to_send, this, sa);
            ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Successful DHEWithCertificate from: " + low_level_sender);
        }
Пример #2
0
        /**
         * Add friend by retreiving certificate from DHT.
         * @param key the DHT key for friend's certificate.
         */
        public void AddDhtFriend(string key)
        {
            if (key == _local_user.DhtKey || _friends.ContainsKey(key))
            {
                if (key != _local_user.DhtKey)
                {
                    _srh.PingFriend(_friends[key]);
                }
                return;
            }

            Channel q = new Channel();

            q.CloseAfterEnqueue();
            q.CloseEvent += delegate(Object o, EventArgs eargs) {
                try {
                    DhtGetResult dgr      = (DhtGetResult)q.Dequeue();
                    byte[]       certData = dgr.value;
                    AddCertificate(certData, key);
                    ProtocolLog.Write(SocialLog.SVPNLog, "ADD DHT SUCCESS: " +
                                      key);
                } catch (Exception e) {
                    ProtocolLog.Write(SocialLog.SVPNLog, e.Message);
                    ProtocolLog.Write(SocialLog.SVPNLog, "ADD DHT FAILURE: " +
                                      key);
                }
            };
            this.Dht.AsGet(key, q);
        }
Пример #3
0
        /**
         * Add local certificate to the DHT.
         */
        public void PublishCertificate()
        {
            byte[]   key_bytes = Encoding.UTF8.GetBytes(_local_user.DhtKey);
            MemBlock keyb      = MemBlock.Reference(key_bytes);
            MemBlock value     = MemBlock.Reference(_local_cert.X509.RawData);

            Channel q = new Channel();

            q.CloseAfterEnqueue();
            q.CloseEvent += delegate(Object o, EventArgs eargs) {
                try {
                    bool success = (bool)(q.Dequeue());
                    if (success)
                    {
                        ProtocolLog.Write(SocialLog.SVPNLog, "PUBLISH CERT SUCCESS: " +
                                          _local_user.DhtKey);
                    }
                } catch (Exception e) {
                    ProtocolLog.Write(SocialLog.SVPNLog, e.Message);
                    ProtocolLog.Write(SocialLog.SVPNLog, "PUBLISH CERT FAILURE: " +
                                      _local_user.DhtKey);
                }
            };
            this.Dht.AsPut(keyb, value, DHTTTL, q);
        }
Пример #4
0
        /// <summary>This helps us leave the Get early if we either have no results or
        /// our remaining results will not reach a majority due to too many nodes
        /// missing data.  This closes the clients returns queue.</summary>
        /// <param name="adgs">The AsDhtGetState to qualify for leaving early</param>
        protected void GetLeaveEarly(AsDhtGetState adgs)
        {
            int left = adgs.queueMapping.Count;
            // Maybe we can leave early
            bool got_all_values = true;

            foreach (DictionaryEntry de in adgs.results)
            {
                int val = ((Hashtable)de.Value).Count;
                if (val < MAJORITY && ((val + left) >= MAJORITY))
                {
                    got_all_values = false;
                    break;
                }
            }

            // If we got to leave early, we must clean up
            if (got_all_values)
            {
                if (Dht.DhtLog.Enabled)
                {
                    ProtocolLog.Write(Dht.DhtLog, String.Format(
                                          "GetLeaveEarly found:left:total = {0}:{1}:{2}",
                                          adgs.results.Count, left, DEGREE));
                }
                adgs.returns.Close();
                adgs.GotToLeaveEarly = true;
            }
        }
Пример #5
0
        /// <summary>3b) Receive a Confirm, verify the entire stack and send a Confirm
        /// 4a)Receive a Confirm, verify the entire stack and all set to go</summary>
        /// <param name="sa">A security association that we wish to perform the
        /// specified control operation on.</param>
        /// <param name="scm">The received SecurityControlMessage.</param>
        /// <param name="scm_reply">A prepared reply message (with headers and such.</param>
        /// <param name="return_path">Where to send the result.</param>
        /// <param name="low_level_sender">We expect the return_path to not be an edge or
        /// some other type of "low level" sender, so this contains the parsed out value.</param>
        protected void HandleControlConfirm(PeerSecAssociation sa,
                                            SecurityControlMessage scm, SecurityControlMessage scm_reply,
                                            ISender return_path, ISender low_level_sender)
        {
            ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Received Confirm from: " + low_level_sender);
            if (sa == null)
            {
                throw new Exception("No valid SA!");
            }
            HashAlgorithm sha1 = new SHA1CryptoServiceProvider();

            scm.Verify((RSACryptoServiceProvider)sa.RemoteCertificate.RSA, sha1);

            if (return_path == low_level_sender)
            {
                sa.VerifyResponse(scm.Hash);
            }
            else
            {
                sa.VerifyRequest(scm.Hash);
                scm_reply.LocalCookie  = scm.RemoteCookie;
                scm_reply.RemoteCookie = scm.LocalCookie;
                scm_reply.Hash         = sa.DHEWithCertificateAndCAsInHash.Value;
                scm_reply.Type         = SecurityControlMessage.MessageType.Confirm;
                lock (_private_key_lock) {
                    scm_reply.Sign(_private_key, sha1);
                }
                ICopyable to_send = new CopyList(SecureControl, scm_reply.Packet);
                return_path.Send(to_send);
            }
            sa.Enable();

            ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Successful Confirm from: " + low_level_sender);
        }
Пример #6
0
        /// <summary>1b) Receive a Cookie which responds with a CookieResponse</summary>
        /// <param name="sa">A security association that we wish to perform the
        /// specified control operation on.</param>
        /// <param name="calc_cookie">Cookie value for the association sender.</param>
        /// <param name="scm">The received SecurityControlMessage.</param>
        /// <param name="scm_reply">A prepared reply message (with headers and such.</param>
        /// <param name="return_path">Where to send the result.</param>
        /// <param name="low_level_sender">We expect the return_path to not be an edge or
        /// some other type of "low level" sender, so this contains the parsed out value.</param>
        protected void HandleControlCookie(PeerSecAssociation sa,
                                           MemBlock calc_cookie, SecurityControlMessage scm,
                                           SecurityControlMessage scm_reply, ISender return_path,
                                           ISender low_level_sender)
        {
            ProtocolLog.WriteIf(ProtocolLog.Security, String.Format(
                                    "{0}, Received Cookie from: {1}, In-Cookie: {2}",
                                    GetHashCode(), low_level_sender, scm.LocalCookie));
            scm_reply.Type         = SecurityControlMessage.MessageType.CookieResponse;
            scm_reply.RemoteCookie = scm.LocalCookie;
            scm_reply.LocalCookie  = calc_cookie;
            if (SecurityPolicy.GetPolicy(scm.SPI).PreExchangedKeys)
            {
                scm_reply.CAs = new List <MemBlock>(0);
            }
            else
            {
                scm_reply.CAs = _ch.SupportedCAs;
            }
            ICopyable to_send = new CopyList(SecureControl, scm_reply.Packet);

            return_path.Send(to_send);
            ProtocolLog.WriteIf(ProtocolLog.Security, String.Format(
                                    "{0}, Successful Cookie from: {1}, Out-Cookie: {2}",
                                    GetHashCode(), low_level_sender, calc_cookie));
        }
Пример #7
0
        /// <summary>This is used to process a dhcp packet on the node side, that
        /// includes placing data such as the local Brunet Address, Ipop Namespace,
        /// and other optional parameters in our request to the dhcp server.  When
        /// receiving the results, if it is successful, the results are written to
        /// the TAP device.</summary>
        /// <param name="ipp"> The IPPacket that contains the Dhcp Request</param>
        /// <param name="dhcp_params"> an object containing any extra parameters for
        /// the dhcp server</param>
        /// <returns> true on if dhcp is supported.</returns>
        protected virtual bool HandleDhcp(IPPacket ipp)
        {
            UdpPacket  udpp        = new UdpPacket(ipp.Payload);
            DhcpPacket dhcp_packet = new DhcpPacket(udpp.Payload);
            MemBlock   ether_addr  = dhcp_packet.chaddr;

            if (_dhcp_config == null)
            {
                return(true);
            }

            DhcpServer dhcp_server = CheckOutDhcpServer(ether_addr);

            if (dhcp_server == null)
            {
                return(true);
            }

            MemBlock last_ip = null;

            _ether_to_ip.TryGetValue(ether_addr, out last_ip);
            byte[] last_ipb = (last_ip == null) ? null : (byte[])last_ip;

            WaitCallback wcb = delegate(object o) {
                ProtocolLog.WriteIf(IpopLog.DhcpLog, String.Format(
                                        "Attempting Dhcp for: {0}", Utils.MemBlockToString(ether_addr, '.')));

                DhcpPacket rpacket = null;
                try {
                    rpacket = dhcp_server.ProcessPacket(dhcp_packet,
                                                        AppNode.Node.Address.ToString(), last_ipb);
                } catch (Exception e) {
                    ProtocolLog.WriteIf(IpopLog.DhcpLog, e.Message);
                    CheckInDhcpServer(dhcp_server);
                    return;
                }

                /* Check our allocation to see if we're getting a new address */
                MemBlock new_addr = rpacket.yiaddr;
                UpdateMapping(ether_addr, new_addr);

                MemBlock destination_ip = ipp.SourceIP;
                if (destination_ip.Equals(IPPacket.ZeroAddress))
                {
                    destination_ip = IPPacket.BroadcastAddress;
                }

                UdpPacket res_udpp = new UdpPacket(_dhcp_server_port, _dhcp_client_port, rpacket.Packet);
                IPPacket  res_ipp  = new IPPacket(IPPacket.Protocols.Udp, rpacket.siaddr,
                                                  destination_ip, res_udpp.ICPacket);
                EthernetPacket res_ep = new EthernetPacket(ether_addr, EthernetPacket.UnicastAddress,
                                                           EthernetPacket.Types.IP, res_ipp.ICPacket);
                Ethernet.Send(res_ep.ICPacket);
                CheckInDhcpServer(dhcp_server);
            };

            ThreadPool.QueueUserWorkItem(wcb);
            return(true);
        }
        /**
         * Checks if the shortcut connection is still optimal, and trims it if not optimal.
         * @param random_target random target pointing to the start of the range for connection candidates.
         * @param score_table candidate addresses sorted by scores.
         * @param sc_address address of the current connection.
         */
        protected void CheckShortcutCallback(Address random_target, SortedList score_table, Address sc_address)
        {
            if (LogEnabled)
            {
                ProtocolLog.Write(ProtocolLog.SCO,
                                  String.Format("SCO local: {0}, Checking shortcut optimality: {1}.",
                                                _node.Address, sc_address));
            }

            int max_rank = (int)Math.Ceiling(0.2 * score_table.Count);

            if (!IsConnectionOptimal(sc_address, score_table, max_rank))
            {
                Address min_target = (Address)score_table.GetByIndex(0);
                //find the connection and trim it.
                Connection to_trim = null;
                foreach (Connection c in _node.ConnectionTable.GetConnections(STRUC_SHORT))
                {
                    string token = c.PeerLinkMessage.Token;
                    if (token == null || token == String.Empty)
                    {
                        continue;
                    }

                    // First half of the token should be the connection initiator
                    string initiator_address = token.Substring(0, token.Length / 2);
                    if (initiator_address == _node.Address.ToString() && c.Address.Equals(sc_address))
                    {
                        to_trim = c;
                        break;
                    }
                }

                if (to_trim != null)
                {
                    if (LogEnabled)
                    {
                        ProtocolLog.Write(ProtocolLog.SCO,
                                          String.Format("SCO local: {0}, Trimming shortcut : {1}, min_target: {2}.",
                                                        _node.Address, to_trim.Address, min_target));
                    }
                    lock (_sync) {
                        double total_secs = (DateTime.UtcNow - to_trim.CreationTime).TotalSeconds;
                        _sum_con_lifetime += total_secs;
                        _trim_count++;
                    }
                    _node.GracefullyClose(to_trim.Edge);
                }
            }
            else
            {
                if (LogEnabled)
                {
                    ProtocolLog.Write(ProtocolLog.SCO,
                                      String.Format("SCO local: {0}, Shortcut is optimal: {1}.",
                                                    _node.Address, sc_address));
                }
            }
        }
Пример #9
0
 public static string Request(string url, Dictionary <string, string>
                              parameters)
 {
     ProtocolLog.WriteIf(SocialLog.SVPNLog,
                         String.Format("HTTP REQUEST: {0} {1} {2}",
                                       DateTime.Now.TimeOfDay, url, parameters["m"]));
     return(Request(url, Encoding.ASCII.GetBytes(UrlEncode(parameters))));
 }
Пример #10
0
        protected void MissedMapping(string ip, Address addr)
        {
            ProtocolLog.WriteIf(IpopLog.ResolverLog, String.Format(
                                    "Notifying remote node of missing address: {0} : {1}", ip, addr));
            ISender sender = new AHExactSender(AppNode.Node, addr);

            AppNode.Node.Rpc.Invoke(sender, null, "Ipop.NoSuchMapping", ip);
        }
Пример #11
0
 /**
  * When the RPC is finished, the Channel is closed, and we handle
  * it here.  This method is only called once.
  */
 protected void QueueCloseHandler(object queue, EventArgs arg)
 {
     ProtocolLog.WriteIf(ProtocolLog.LinkDebug,
                         String.Format("{0}: Connector Finished: {1}, {2}, results: {3}",
                                       _local_node.Address, _sender, State, _got_ctms.Count));
     System.Threading.Interlocked.Exchange(ref _is_finished, 1);
     FireFinished();
 }
Пример #12
0
 private void PostEvent(Events.EventInfo eventInfo)
 {
     lock (_events)
     {
         _events.Enqueue(eventInfo);
         _eventReceived.Set();
     }
     ProtocolLog.Write(eventInfo);
 }
Пример #13
0
        /// <summary>Parses web data and updates the revoked users hashtable if
        /// successful</summary>
        protected void UpdateRl(byte[] data)
        {
            // message is length (4) + date (8) + data (variable) + hash (~20)
            int length = data.Length;

            if (length < 12)
            {
                throw new Exception("No data?  Didn't get enough data...");
            }

            length = NumberSerializer.ReadInt(data, 0);
            DateTime date = new DateTime(NumberSerializer.ReadLong(data, 4));

            // warn the user that this is an old revocation list, maybe there is an attack
            if (date < DateTime.UtcNow.AddHours(-24))
            {
                ProtocolLog.WriteIf(IpopLog.GroupVPN, "Revocation list is over 24 hours old");
            }

            // Weird, data length is longer than the data we got
            if (length > data.Length - 12)
            {
                throw new Exception("Missing data?  Didn't get enough data...");
            }

            // hash the data and verify the signature
            SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

            byte[] hash      = sha1.ComputeHash(data, 4, length);
            byte[] signature = new byte[data.Length - 4 - length];
            Array.Copy(data, 4 + length, signature, 0, signature.Length);

            if (!_ca_cert.PublicKey.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), signature))
            {
                throw new Exception("Invalid signature!");
            }

            // convert the data to an array list as it was sent to us
            MemBlock mem = MemBlock.Reference(data, 12, length - 8);

            ArrayList rl = AdrConverter.Deserialize(mem) as ArrayList;

            if (rl == null)
            {
                throw new Exception("Data wasn't a list...");
            }

            // convert it into a hashtable for O(1) look ups
            Hashtable ht = new Hashtable();

            foreach (string username in rl)
            {
                ht[username] = true;
            }

            Interlocked.Exchange(ref _revoked_users, ht);
        }
Пример #14
0
 protected void Log(string format_string, params object[] format_args)
 {
     if (LogEnabled)
     {
         string s = String.Format(format_string, format_args);
         ProtocolLog.Write(ProtocolLog.MapReduce,
                           String.Format("{0}: {1}, {2}", _node.Address, this.GetType(), s));
     }
 }
Пример #15
0
 /**
  * This just echos back the object passed to it
  */
 public object Ping(object o, ISender edge)
 {
     if (ProtocolLog.LinkDebug.Enabled)
     {
         ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                               "{0} sys:link.Ping({1},{2})", _node.Address, o, edge));
     }
     return(o);
 }
Пример #16
0
        override protected bool HandleIncoming(MemBlock data, out MemBlock app_data)
        {
            app_data = null;
            int count = 0;

            lock (_buffer_sync) {
                if (data != null)
                {
                    data.CopyTo(_buffer, 0);
                    _read.Write(_buffer, data.Length);
                }

                count = _ssl.Read(_buffer, _buffer.Length);
                if (count > 0)
                {
                    app_data = MemBlock.Copy(_buffer, 0, count);
                }
            }

            if (app_data != null)
            {
                // If the read was successful, Dtls has received an incoming data
                // message and decrypted it
                return(true);
            }
            else
            {
                SslError error = _ssl.GetError(count);
                if (error == SslError.SSL_ERROR_WANT_READ)
                {
                    if (SslState == SslState.OK)
                    {
                        UpdateState(States.Active);
                        // In the SslCtx verify, there's no way to get the underlying Sender
                        _ch.Verify(RemoteCertificate, Sender);
                    }
                    HandleWouldBlock();
                }
                else if (error == SslError.SSL_ERROR_SSL)
                {
                    var ose = new OpenSslException();
                    Close("Received unrecoverable error: " + ose.ToString());
                    throw ose;
                }
                else if (error == SslError.SSL_ERROR_ZERO_RETURN)
                {
                    Close("Received clean close notification");
                }
                else
                {
                    ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions,
                                        "Receive other: " + error);
                }
            }
            return(false);
        }
Пример #17
0
        override public void Set(Address addr)
        {
            if (!_cache.Update(addr, true))
            {
                return;
            }

            ProtocolLog.WriteIf(ProtocolLog.OnDemandCO, "Trying: " + addr);
            ConnectTo(addr);
        }
Пример #18
0
 public void Start()
 {
     try {
         _eh(_n, EventArgs.Empty);
     }
     catch (Exception x) {
         ProtocolLog.WriteIf(ProtocolLog.Exceptions, String.Format(
                                 "Exception in heartbeat event : {0}", x));
     }
 }
Пример #19
0
    /**
    <summary>The _listen_threads method, reads from sockets and let's the node
    handle the incoming data.</summary>
    */
    protected void Listen() {
      if (Thread.CurrentThread.Name == null) {
        Thread.CurrentThread.Name = "iphandler_thread";
      }
      ArrayList sockets = new ArrayList();
      sockets.Add(_uc);
      if(_mc != null) {
        sockets.Add(_mc);
      }

      byte[] buffer =  new byte[Int16.MaxValue];
      DateTime last_debug = DateTime.UtcNow;
      TimeSpan debug_period = TimeSpan.FromSeconds(5);
      while(1 == _running) {
        if (ProtocolLog.Monitor.Enabled) {
          DateTime now = DateTime.UtcNow;
          if (now - last_debug > debug_period) {
            last_debug = now;
            ProtocolLog.Write(ProtocolLog.Monitor, String.Format("I am alive: {0}", now));
          }
        }
        try {
          ArrayList readers = (ArrayList) sockets.Clone();
          Socket.Select(readers, null, null, 10000000); //10 seconds
          foreach(Socket socket in readers) {
            EndPoint ep = new IPEndPoint(IPAddress.Any, 0);
            int rec_bytes = socket.ReceiveFrom(buffer, ref ep);
            Subscriber s = _sub;
            //s can't change once we've read it.
            if( s != null && rec_bytes > 0) {
              MemBlock packet = MemBlock.Copy(buffer, 0, rec_bytes);
              MemBlock cookie = packet.Slice(0, 4);
              if(cookie.Equals(MagicCookie)) {
                packet = packet.Slice(4);
                ISender sender = CreateUnicastSender(ep);
                s.Handle(packet, sender);
              }
            }
          }
        }
        catch(ObjectDisposedException odx) {
          //If we are no longer running, this is to be expected.
          if(1 == _running) {
          //If we are running print it out
            ProtocolLog.WriteIf(ProtocolLog.Exceptions, odx.ToString());
          }
          break;
        }
        catch(Exception x) {
          if(0 == _running) {
            ProtocolLog.WriteIf(ProtocolLog.Exceptions, x.ToString());
          }
        }
      }
    }
Пример #20
0
 /// <summary>Timercall back for internal ssl timeout.</summary>
 private void HandleWouldBlock(DateTime now)
 {
     Interlocked.Exchange(ref _fe_lock, 0);
     try {
         HandleWouldBlock();
     } catch (Exception e) {
         Close("Unhandled exception: " + e.ToString());
         ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions,
                             this + "\n" + e.ToString());
     }
 }
Пример #21
0
        /// <summary>Incoming IQ, process it and pass it to the proper HandleQuery,
        /// if one exists.</summary>
        protected void HandleIQ(object sender, IQ iq)
        {
            if (iq.Query == null)
            {
                return;
            }
            ProtocolLog.WriteIf(XmppLog, "Incoming: " + iq.ToString());

            // If we don't set true, it will respond with an error
            iq.Handled = HandleQuery(iq.Query as Element, iq.From);
        }
Пример #22
0
            /**
             * Update the ReadSocks and ErrorSocks to see which sockets might be
             * ready for reading or need closing.
             */
            public void Select()
            {
                ReadSocks.Clear();
                ErrorSocks.Clear();
                WriteSocks.Clear();
                ReadSocks.AddRange(AllSockets);
                //Also listen for incoming connections:
                ReadSocks.Add(ListenSock);

                /*
                 * POB: I cannot find any documentation on what, other than
                 * out-of-band data, might be signaled with these.  As such
                 * I am commenting them out.  If we don't see a reason to put
                 * it back soon, please delete ErrorSocks from the code.
                 * 11/19/2008
                 * ErrorSocks.AddRange(AllSockets);
                 */
                //Here we do non-blocking connecting:
                WriteSocks.AddRange(_con_socks);
                //Here we add the sockets that are waiting to write:
                WriteSocks.AddRange(_socks_to_send);
                //An error signals that the connection failed
                ErrorSocks.AddRange(_con_socks);

                /*
                 * Now we are ready to do our select and we only act on local
                 * variables
                 */
                try {
                    //Socket.Select(ReadSocks, null, ErrorSocks, TIMEOUT_MS * 1000);
                    Socket.Select(ReadSocks, WriteSocks, ErrorSocks, TIMEOUT_MS * 1000);
                    //Socket.Select(ReadSocks, null, null, TIMEOUT_MS * 1000);
                }
                catch (System.ObjectDisposedException) {
                    /*
                     * This happens if one of the edges is closed while
                     * a select call is in progress.  This is not weird,
                     * just ignore it
                     */
                    ReadSocks.Clear();
                    ErrorSocks.Clear();
                    WriteSocks.Clear();
                }
                catch (Exception x) {
                    /*
                     * There could be an OS error, in principle.  If this
                     * happens, log it, and just sleep for the period of time
                     * we would have waited (to prevent us from spinning in
                     * this thread).
                     */
                    ProtocolLog.Write(ProtocolLog.Exceptions, x.ToString());
                    Thread.Sleep(TIMEOUT_MS);
                }
            }
Пример #23
0
 override protected void ObtainedConnection(Connection con)
 {
     if (ConnectionDesired(con.Address))
     {
         ProtocolLog.WriteIf(ProtocolLog.OnDemandCO, "Got connection: " + con);
     }
     else if (con.ConType.Equals(Type))
     {
         DelayedRemove(con.Address);
     }
 }
Пример #24
0
        /**
         * Starts all edge listeners for the node.
         * Useful for connect/disconnect operations
         */
        protected virtual void StartAllEdgeListeners()
        {
            foreach (EdgeListener el in _edgelistener_list)
            {
                ProtocolLog.WriteIf(ProtocolLog.NodeLog, String.Format(
                                        "{0} starting {1}", Address, el));

                el.Start();
            }
            Interlocked.Exchange(ref _running, 1);
        }
Пример #25
0
 /// <summary>1a) Send a Cookie</summary>
 /// <param name="sa">A security association that we wish to perform the
 /// specified control operation on.</param>
 protected void HandleControlNoSuchSA(PeerSecAssociation sa)
 {
     if (sa == null)
     {
         ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " NoSuchSA received, but we have no SA either!");
     }
     else
     {
         ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " NoSuchSA received, handling...");
         StartSA(sa);
     }
 }
        /**
         * Initiates creation of a bypass connection.
         *
         */
        protected void CreateBypass()
        {
            if (LogEnabled)
            {
                ProtocolLog.Write(ProtocolLog.SCO,
                                  String.Format("SCO local: {0}, Selecting bypass to create.",
                                                _node.Address));
            }
            double logk = Math.Log((double)_node.NetworkSize, 2.0);

            _target_selector.ComputeCandidates(_node.Address, (int)Math.Ceiling(logk), CreateBypassCallback, null);
        }
        /**
         * Checks if we have the optimal bypass connection, and trims the ones that are unnecessary.
         * @param start random target pointing to the start of the range for connection candidates.
         * @param score_table candidate addresses sorted by scores.
         * @param bp_address address of the current connection (nullable).
         */
        protected void CheckBypassCallback(Address start, SortedList score_table, Address bp_address)
        {
            if (ProtocolLog.SCO.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.SCO,
                                  String.Format("SCO local: {0}, Checking bypass optimality.",
                                                _node.Address));
            }

            ArrayList bypass_cons = new ArrayList();

            foreach (Connection c in _node.ConnectionTable.GetConnections(STRUC_BYPASS))
            {
                string token = c.State.PeerLinkMessage.Token;
                if (token == null || token.Equals(_node.Address.ToString()))
                {
                    continue;
                }
                bypass_cons.Add(c);
            }

            int max_rank = bypass_cons.Count > 1 ? 0: (int)Math.Ceiling(0.2 * score_table.Count);

            foreach (Connection bp in bypass_cons)
            {
                if (!IsConnectionOptimal(bp.Address, score_table, max_rank))
                {
                    Address min_target = (Address)score_table.GetByIndex(0);
#if TRACE
                    if (ProtocolLog.SCO.Enabled)
                    {
                        ProtocolLog.Write(ProtocolLog.SCO,
                                          String.Format("SCO local: {0}, Trimming bypass : {1}, min_target: {2}.",
                                                        _node.Address, bp.Address, min_target));
                    }
#endif
                    lock (_sync) {
                        double total_secs = (DateTime.UtcNow - bp.CreationTime).TotalSeconds;
                        _sum_con_lifetime += total_secs;
                        _trim_count++;
                    }
                    bp.Close(_node.Rpc, String.Empty);
#if TRACE
                }
                else if (ProtocolLog.SCO.Enabled)
                {
                    ProtocolLog.Write(ProtocolLog.SCO,
                                      String.Format("SCO local: {0}, Bypass is optimal: {1}.",
                                                    _node.Address, bp));
#endif
                }
            }
        }
Пример #28
0
            public override void Start(SocketState ss)
            {
                DateTime now = DateTime.UtcNow;

                if (now - _last_debug > _debug_period)
                {
                    _last_debug = now;
                    ProtocolLog.Write(ProtocolLog.Monitor, String.Format("I am alive: {0}", now));
                }
                //Run ourselves again later.
                _q.Enqueue(this);
            }
Пример #29
0
        override public void HandleData(MemBlock data, ISender return_path, object state)
        {
            SecurityAssociation sa = return_path as SecurityAssociation;

            if (sa == null)
            {
                ProtocolLog.WriteIf(ProtocolLog.Exceptions, String.Format(
                                        "Insecure sender {0} sent ptype {1}", return_path, _ptype));
                return;
            }
            base.HandleData(data, return_path, state);
        }
Пример #30
0
        /**
         * When we're here, we have the status message
         */
        protected void StatusCloseHandler(object q, EventArgs args)
        {
            try {
                Channel resq = (Channel)q;
                //If we got no result
                RpcResult     res = (RpcResult)resq.Dequeue();
                StatusMessage sm  = new StatusMessage((IDictionary)res.Result);
                if (_node.EdgeVerifyMethod != null)
                {
                    if (!_node.EdgeVerifyMethod(_node, _e, LinkMessageReply.Local.Address))
                    {
                        throw new Exception("Edge verification failed!");
                    }
                }

                Connection c = new Connection(_e, LinkMessageReply.Local.Address,
                                              _contype, sm, LinkMessageReply);
                _node.ConnectionTable.Add(c);
                _con.Value = c;
                Finish(Result.Success);
            }
            catch (InvalidOperationException) {
                /*
                 * This is unexpected.
                 */
                string message = String.Format(
                    "No StatusMessage returned from open({1}) Edge: {0}",
                    _e, !_e.IsClosed);
                if (ProtocolLog.LinkDebug.Enabled)
                {
                    ProtocolLog.Write(ProtocolLog.LinkDebug, message);
                }

                /*
                 * We got a link message from this guy, but not a status response,
                 * so let's try this TA again.
                 */
                Finish(Result.RetryThisTA);
            }
            catch (Exception x) {
                /*
                 * Clearly we got some response from this edge, but something
                 * unexpected happened.  Let's try it this edge again if we
                 * can
                 */
                if (ProtocolLog.LinkDebug.Enabled)
                {
                    ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                          "LPS.StatusResultHandler Exception: {0}", x));
                }
                Finish(Result.RetryThisTA);
            }
        }