상속: Edge
예제 #1
0
            protected void HandleWrites(SocketState ss)
            {
                ArrayList socks = ss.WriteSocks;

                for (int i = 0; i < socks.Count; i++)
                {
                    Socket        s  = (Socket)socks[i];
                    CreationState cs = ss.TakeCreationState(s);
                    if (cs != null)
                    {
                        cs.HandleWritability(s);
                    }
                    else
                    {
                        //Let's try to flush the buffer:
                        try {
                            ss.FlushSocket(s);
                        }
                        catch {
                            /*
                             * We should close this edge
                             */
                            TcpEdge tcpe = ss.GetEdge(s);
                            TEL.RequestClose(tcpe);
                            //Go ahead and forget about this socket.
                            CloseAction ca = new CloseAction(tcpe, null);
                            ca.Start(ss);
                        }
                    }
                }
            }
예제 #2
0
 /**
  * Called when the socket is writable
  */
 public void HandleWritability(Socket s)
 {
     try {
         if (s.Connected)
         {
             TcpEdgeListener.SetSocketOpts(s);
             TcpEdge e = new TcpEdge(TEL, false, s);
             Result.Value = e;
             //Handle closes in the select thread:
             CloseAction ca = new CloseAction(e, TEL.ActionQueue);
             e.CloseEvent += ca.CloseHandler;
             //Set the edge
             TEL.ActionQueue.Enqueue(this);
         }
         else
         {
             //This did not work out, close the socket and release the resources:
             HandleError(s);
         }
     }
     catch (Exception) {
         //This did not work out, close the socket and release the resources:
         //Console.WriteLine("Exception: {0}", x);
         HandleError(s);
     }
 }
예제 #3
0
            public override void Start(SocketState ss)
            {
                /*
                 * Note, we are the only thread running actions from the queue,
                 * so, no change to ss can happen concurrently with this logic
                 */
                ArrayList close_actions = new ArrayList();

                foreach (Socket s in ss.AllSockets)
                {
                    TcpEdge e = ss.GetEdge(s);
                    TEL.RequestClose(e);

                    /*
                     * We can't just call ca.Start(ss) because that
                     * would change ss.AllSockets
                     */
                    close_actions.Add(new CloseAction(e, null));
                }
                foreach (CloseAction ca in close_actions)
                {
                    ca.Start(ss);
                }
                //Close the main socket:
                ss.ListenSock.Close();
            }
예제 #4
0
            /*
             * Update the SocketState.TAA and check to see if any Edges need
             * to be closed.
             */
            public override void Start(SocketState ss)
            {
                ss.TAA = TAA;
                ArrayList bad_edges = new ArrayList();

                foreach (Socket s in ss.AllSockets)
                {
                    TcpEdge e = ss.GetEdge(s);
                    if (e != null)
                    {
                        if (TAA.Authorize(e.RemoteTA) == TAAuthorizer.Decision.Deny)
                        {
                            //We can't close now, that would invalidate the AllSockets
                            //iterator
                            bad_edges.Add(e);
                        }
                    }
                }
                foreach (TcpEdge e in bad_edges)
                {
                    EL.RequestClose(e);
                    CloseAction ca = new CloseAction(e, null);
                    ca.Start(ss);
                }
            }
예제 #5
0
            /**
             * Implements the SocketStateAction interface.  This is called to trigger the ECB
             * in the SelectThread so we don't have to worry about multiple threads
             * accessing variables.
             */
            public override void Start(SocketState ss)
            {
                object result = Result.Value;

                if (result != null)
                {
                    TcpEdge new_edge = result as TcpEdge;
                    if (new_edge != null)
                    {
                        //Tell the world about the new Edge:
                        ss.AddEdge(new_edge);
                        ECB(true, new_edge, null);
                    }
                    else
                    {
                        ECB(false, null, (Exception)result);
                    }
                }
                else
                {
                    //Try to make a new start:
                    if (IPAddressQueue.Count <= 0)
                    {
                        ECB(false, null, new EdgeException("No more IP Addresses"));
                    }
                    else
                    {
                        Socket s = null;
                        try {
                            s = new Socket(AddressFamily.InterNetwork,
                                           SocketType.Stream,
                                           ProtocolType.Tcp);
                            s.Blocking = false;
                            ss.AddCreationState(s, this);
                            IPAddress  ipaddr = (IPAddress)IPAddressQueue.Dequeue();
                            IPEndPoint end    = new IPEndPoint(ipaddr, Port);
                            //This is a hack because of a bug in MS.Net and Mono:
                            //https://bugzilla.novell.com/show_bug.cgi?id=349449
                            //http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=332142
                            s.Bind(new IPEndPoint(IPAddress.Any, 0));
                            s.Connect(end);
                        }
                        catch (SocketException sx) {
                            if (sx.SocketErrorCode != SocketError.WouldBlock)
                            {
                                if (s != null)
                                {
                                    ss.TakeCreationState(s);
                                }
                                ECB(false, null, new EdgeException(false, "Could not Connect", sx));
                            }
                            /* else Ignore the non-blocking socket error */
                        }
                    }
                }
            }
예제 #6
0
            public void AddEdge(TcpEdge e)
            {
                Socket s = e.Socket;

                AllSockets.Add(s);
                ReceiveState rs = new ReceiveState(e, BA);

                _sock_to_rs[s] = rs;
                Interlocked.Increment(ref TEL._count);
            }
예제 #7
0
            public void RemoveEdge(TcpEdge e)
            {
                Socket s = e.Socket;

                if (false == _sock_to_rs.Contains(s))
                {
                    return;
                }
                // Go ahead and remove from the map. ... this needs to be done because
                // Socket's dynamic HashCode, a bug in an older version of Mono
                Hashtable new_s_to_rs = new Hashtable(_sock_to_rs.Count);

                foreach (DictionaryEntry de in _sock_to_rs)
                {
                    ReceiveState trs = (ReceiveState)de.Value;
                    if (e != trs.Edge)
                    {
                        new_s_to_rs.Add(de.Key, trs);
                    }
                }
                _sock_to_rs = new_s_to_rs;
                AllSockets.Remove(s);
                _socks_to_send.Remove(s);
                Interlocked.Decrement(ref TEL._count);
                //We shouldn't be sending at the same time:
                lock ( e ) {
                    //We need to shutdown the socket:
                    try {
                        //Don't let more reading or writing:
                        s.Shutdown(SocketShutdown.Both);
                    }
                    catch { }
                    finally {
                        //This can't throw an exception
                        s.Close();
                    }
                }
            }
예제 #8
0
        public void HandleEdgeSend(Edge from, ICopyable p)
        {
            TcpEdge sender = (TcpEdge)from;

            try {
                bool flushed = true;
                lock ( sender ) {
                    //Try to fill up the buffer:
                    sender.WriteToBuffer(p);
                    //Okay, we loaded the whole packet into the TcpEdge's buffer
                    //now it is time to try to flush the buffer:
                    flushed = sender.Flush();
                }
                if (!flushed)
                {
                    /*
                     * We should remember to try again when the socket is
                     * writable
                     */
                    ActionQueue.Enqueue(new SendWaitAction(sender.Socket));
                }
            }
            catch (EdgeException ex) {
                if (false == ex.IsTransient)
                {
                    //Go ahead and forget about this socket.
                    RequestClose(from);
                    ActionQueue.Enqueue(new CloseAction(sender, null));
                }
                //Rethrow the exception
                throw;
            }
            catch (Exception x) {
                //Assume any other error is transient:
                throw new EdgeException(true, String.Format("Could not send on: {0}", from), x);
            }
        }
예제 #9
0
            protected void HandleReads(SocketState ss)
            {
                ArrayList readsocks   = ss.ReadSocks;
                Socket    listen_sock = ss.ListenSock;

                for (int i = 0; i < readsocks.Count; i++)
                {
                    Socket s = (Socket)readsocks[i];
                    //See if this is a new socket
                    if (s == listen_sock)
                    {
                        TcpEdge e     = null;
                        Socket  new_s = null;
                        try {
                            new_s = listen_sock.Accept();
                            IPEndPoint rep = (IPEndPoint)new_s.RemoteEndPoint;
                            new_s.LingerState = new LingerOption(true, 0);
                            TransportAddress rta =
                                TransportAddressFactory.CreateInstance(TransportAddress.TAType.Tcp, rep);
                            if (ss.TAA.Authorize(rta) == TAAuthorizer.Decision.Deny)
                            {
                                //No thank you Dr. Evil
                                Console.Error.WriteLine("Denying: {0}", rta);
                                new_s.Close();
                            }
                            else
                            {
                                //This edge looks clean
                                TcpEdgeListener.SetSocketOpts(s);
                                e = new TcpEdge(TEL, true, new_s);
                                ss.AddEdge(e);
                                //Handle closes in the select thread:
                                CloseAction ca = new CloseAction(e, TEL.ActionQueue);
                                e.CloseEvent += ca.CloseHandler;
                                TEL.SendEdgeEvent(e);
                            }
                        }
                        catch (Exception) {
                            //Looks like this Accept has failed.  Do nothing
                            //Console.Error.WriteLine("New incoming edge ({0}) failed: {1}", new_s, sx);
                            //Make sure the edge is closed
                            if (e != null)
                            {
                                TEL.RequestClose(e);
                                //Go ahead and forget about this socket.
                                CloseAction ca = new CloseAction(e, null);
                                ca.Start(ss);
                            }
                            else if (new_s != null)
                            {
                                //This should not be able to throw an exception:
                                new_s.Close();
                            }
                        }
                    }
                    else
                    {
                        ReceiveState rs = ss.GetReceiveState(s);
                        if (rs != null && !rs.Receive())
                        {
                            TEL.RequestClose(rs.Edge);
                            //Go ahead and forget about this socket.
                            CloseAction ca = new CloseAction(rs.Edge, null);
                            ca.Start(ss);
                        }
                    }
                }
            }
예제 #10
0
 public CloseAction(TcpEdge e, LockFreeQueue <SocketStateAction> q)
 {
     _e     = e;
     _queue = q;
 }
예제 #11
0
 public void RemoveEdge(TcpEdge e)
 {
   Socket s = e.Socket;
   if( false == _sock_to_rs.Contains(s) ) {
     return;
   }
   // Go ahead and remove from the map. ... this needs to be done because
   // Socket's dynamic HashCode, a bug in an older version of Mono
   Hashtable new_s_to_rs = new Hashtable( _sock_to_rs.Count );
   foreach(DictionaryEntry de in _sock_to_rs) {
     ReceiveState trs = (ReceiveState)de.Value;
     if( e != trs.Edge ) {
       new_s_to_rs.Add( de.Key, trs );
     }
   }
   _sock_to_rs = new_s_to_rs;
   AllSockets.Remove(s); 
   _socks_to_send.Remove(s);
   Interlocked.Decrement(ref TEL._count);
   //We shouldn't be sending at the same time:
   lock( e ) {
     //We need to shutdown the socket:
     try {
       //Don't let more reading or writing:
       s.Shutdown(SocketShutdown.Both);
     }
     catch { }
     finally {
       //This can't throw an exception
       s.Close();
     }
   }
 }
예제 #12
0
 public ReceiveState(TcpEdge e, BufferAllocator ba) {
   Edge = e;
   _s = e.Socket;
   _ba = ba;
 }
예제 #13
0
 protected void HandleReads(SocketState ss) {
   ArrayList readsocks = ss.ReadSocks;
   Socket listen_sock = ss.ListenSock;
   for(int i = 0; i < readsocks.Count; i++) {
     Socket s = (Socket)readsocks[i];
     //See if this is a new socket
     if( s == listen_sock ) {
       TcpEdge e = null;
       Socket new_s = null;
       try {
         new_s = listen_sock.Accept();
         IPEndPoint rep = (IPEndPoint)new_s.RemoteEndPoint;
         new_s.LingerState = new LingerOption (true, 0);
         TransportAddress rta =
                  TransportAddressFactory.CreateInstance(TransportAddress.TAType.Tcp, rep);
         if( ss.TAA.Authorize(rta) == TAAuthorizer.Decision.Deny ) {
           //No thank you Dr. Evil
           Console.Error.WriteLine("Denying: {0}", rta);
           new_s.Close();
         }
         else {
           //This edge looks clean
           TcpEdgeListener.SetSocketOpts(s);
           e = new TcpEdge(TEL, true, new_s);
           ss.AddEdge(e);
           //Handle closes in the select thread:
           CloseAction ca = new CloseAction(e, TEL.ActionQueue);
           e.CloseEvent += ca.CloseHandler;
           TEL.SendEdgeEvent(e);
         }
       }
       catch(Exception) {
         //Looks like this Accept has failed.  Do nothing
         //Console.Error.WriteLine("New incoming edge ({0}) failed: {1}", new_s, sx);
         //Make sure the edge is closed
         if( e != null ) {
           TEL.RequestClose(e);
           //Go ahead and forget about this socket.
           CloseAction ca = new CloseAction(e, null);
           ca.Start(ss);
         }
         else if( new_s != null) {
           //This should not be able to throw an exception:
           new_s.Close();
         }
       }
     }
     else {
       ReceiveState rs = ss.GetReceiveState(s);
       if( rs != null && !rs.Receive() ) {
         TEL.RequestClose(rs.Edge);
         //Go ahead and forget about this socket.
         CloseAction ca = new CloseAction(rs.Edge, null);
         ca.Start(ss);
       }
     }
   }
 }
예제 #14
0
 /**
  * Called when the socket is writable
  */
 public void HandleWritability(Socket s) {
   try {
     if( s.Connected ) {
       TcpEdgeListener.SetSocketOpts(s);
       TcpEdge e = new TcpEdge(TEL, false, s);
       Result.Value = e;
       //Handle closes in the select thread:
       CloseAction ca = new CloseAction(e, TEL.ActionQueue);
       e.CloseEvent += ca.CloseHandler;
       //Set the edge
       TEL.ActionQueue.Enqueue(this);
     }
     else {
       //This did not work out, close the socket and release the resources:
       HandleError(s);
     }
   }
   catch(Exception) {
     //This did not work out, close the socket and release the resources:
     //Console.WriteLine("Exception: {0}", x);
     HandleError(s);
   }
 }
예제 #15
0
 public CloseAction(TcpEdge e, LockFreeQueue<SocketStateAction> q) {
   _e = e;
   _queue = q;
 }
예제 #16
0
 public ReceiveState(TcpEdge e, BufferAllocator ba)
 {
     Edge = e;
     _s   = e.Socket;
     _ba  = ba;
 }
예제 #17
0
 public void AddEdge(TcpEdge e) {
   Socket s = e.Socket;
   AllSockets.Add(s); 
   ReceiveState rs = new ReceiveState(e, BA);
   _sock_to_rs[s] = rs;
   Interlocked.Increment(ref TEL._count);
 }