예제 #1
0
 public ReceiveState(TcpEdge e, BufferAllocator ba) {
   Edge = e;
   _s = e.Socket;
   _ba = ba;
 }
예제 #2
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);
       }
     }
   }
 }
예제 #3
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);
   }
 }
예제 #4
0
 public CloseAction(TcpEdge e, LockFreeQueue<SocketStateAction> q) {
   _e = e;
   _queue = q;
 }
예제 #5
0
 public void RemoveEdge(TcpEdge e)
 {
   Socket s = e.Socket;
   // 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();
     }
   }
 }
예제 #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);
 }