ACE::INet::ConnectionHolder*
    SessionFactory_Impl::create_connection (
        const ACE::INet::ConnectionKey& key) const
      {
        INET_TRACE ("HTTP_SessionFactory_Impl::create_connection");

        const ClientRequestHandler::HttpConnectionKey& ikey =
            dynamic_cast<const ClientRequestHandler::HttpConnectionKey&> (key);

        SessionHolder_Impl* session_holder = 0;
        ACE_NEW_RETURN (session_holder,
                        SessionHolder_Impl (),
                        0);
        ACE_Auto_Ptr<SessionHolder_Impl> session_safe_ref (session_holder);

        (*session_holder)->set_host (ikey.host (), ikey.port ());
        if (ikey.is_proxy_connection ())
          {
            (*session_holder)->set_proxy_target (ikey.proxy_target_host (),
                                                 ikey.proxy_target_port ());
          }

        if ((*session_holder)->connect (true))
          {
            return session_safe_ref.release ();
          }

        return 0;
      }
Beispiel #2
0
 Session_T<ACE_SYNCH_USE>::Session_T (bool keep_alive)
   : SessionBase (URL::HTTP_PORT, keep_alive),
     connection_ (0),
     sock_stream_ (0)
   {
     INET_TRACE ("ACE_HTTP_Session - ctor");
   }
Beispiel #3
0
    bool ConnectionCache::claim_existing_connection(const ConnectionKey& key,
                                                    connection_type*& connection,
                                                    ConnectionCacheValue::State& state)
      {
        INET_TRACE ("ConnectionCache::claim_existing_connection");

        ConnectionCacheValue cacheval;
        if (this->find_connection (key, cacheval))
          {
            state = cacheval.state ();
            if (state == ConnectionCacheValue::CST_IDLE)
              {
                cacheval.state (ConnectionCacheValue::CST_BUSY);
                if (this->set_connection (key, cacheval))
                  {
                    connection = cacheval.connection ();
                    return true;
                  }
                else
                  {
                    INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ConnectionCache::claim_existing_connection - ")
                                              ACE_TEXT ("failed to claim connection entry")));
                  }
              }
          }
        return false;
      }
Beispiel #4
0
    bool Session_T<ACE_SYNCH_USE>::attach_connection (connection_type* connection)
      {
        INET_TRACE ("ACE_HTTP_Session::attach_connection");

        if (!connection->is_connected ())
          return false;

        this->close ();

        ACE_INET_Addr remote;
        connection->peer ().get_remote_addr (remote);
        this->host_ = remote.get_host_name ();
        this->port_ = remote.get_port_number ();

        this->connection_ = connection;
        this->connection_->add_reference ();

        ACE_NEW_NORETURN (this->sock_stream_,
                          sock_stream_type (this->connection_));

        if (this->sock_stream_)
          {
            this->keep_alive_ = true;
            this->keep_alive_timeout_ = ACE_Time_Value::zero;
            this->cannot_reconnect_ = true;
            return true;
          }
        else
          {
            this->close ();
            return false;
          }
      }
Beispiel #5
0
    bool ConnectionCache::release_connection(const ConnectionKey& key,
                                             connection_type* connection)
      {
        INET_TRACE ("ConnectionCache::release_connection");

        INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::release_connection - ")
                                 ACE_TEXT ("releasing connection\n")));

        ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX,
                                  guard_,
                                  this->lock_,
                                  false));

        ConnectionCacheValue cacheval;
        if (this->find_connection (key, cacheval) &&
              cacheval.connection () == connection &&
              cacheval.state () == ConnectionCacheValue::CST_BUSY)
          {
            cacheval.state (ConnectionCacheValue::CST_IDLE);
            if (this->set_connection (key, cacheval))
              {
                // signal other threads about free connection
                this->condition_.broadcast ();
                return true;
              }
            else
              {
                INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ConnectionCache::release_connection - ")
                                          ACE_TEXT ("failed to release connection entry")));
                return false;
              }
          }
        else
          return false;
      }
Beispiel #6
0
int
t_getsockopt(long s,
   int   level,
   int   name,
   void *   arg,
   int   arglen)

{
   struct socket *   so;
   int   err;

   so = LONG2SO(s);
   SOC_CHECK(so);
   USE_ARG(level);
   USE_ARG(arglen);

   LOCK_NET_RESOURCE (NET_RESID);

   INET_TRACE (INETM_SOCKET,
    ("INET: getsockopt: name %x val %x valsize %d\n",
    name, val));

   /* is it a level IP_OPTIONS call? */
   if (level != IP_OPTIONS)
   {
      if ((err = sogetopt (so, name, arg)) != 0) 
      {
         so->so_error = err;
         UNLOCK_NET_RESOURCE (NET_RESID);
         return SOCKET_ERROR;
      }
   }
   else
   {
      /* level 1 options are for the IP packet level.
       * the info is carried in the socket CB, then put 
       * into the PACKET.
       */
      if (name == IP_TTL_OPT)
      {
         if (!so->so_optsPack) *(int *)arg = IP_TTL;
         else *(int *)arg = (int)so->so_optsPack->ip_ttl;
      }
      else if (name == IP_TOS)
      {
         if (!so->so_optsPack) *(int *)arg = IP_TOS_DEFVAL;
         else *(int *)arg = (int)so->so_optsPack->ip_tos;
      }
      else
      {
         UNLOCK_NET_RESOURCE (NET_RESID);
         return SOCKET_ERROR;
      }
   }   
   so->so_error = 0;

   UNLOCK_NET_RESOURCE (NET_RESID);
   return 0;
}
Beispiel #7
0
 Session_T<ACE_SYNCH_USE>::Session_T (const ACE_Time_Value& timeout,
                                      bool keep_alive,
                                      const ACE_Time_Value* alive_timeout)
   : SessionBase (URL::HTTP_PORT, timeout, keep_alive, alive_timeout),
     connection_ (0),
     sock_stream_ (0)
   {
     INET_TRACE ("ACE_HTTP_Session - ctor");
   }
Beispiel #8
0
    bool Session_T<ACE_SYNCH_USE>::receive_response (Response& response)
      {
        INET_TRACE ("ACE_FTP_Session::receive_response");

        this->sock_stream_->flush ();

        response.reset ();
        return response.read (*this->sock_stream_);
      }
Beispiel #9
0
 Session_T<ACE_SYNCH_USE>::Session_T (const ACE_Time_Value& timeout)
   : port_ (FTP_PORT),
     reactive_ (false),
     connection_ (0),
     sock_stream_ (0),
     ftp_timeout_ (timeout),
     cannot_reconnect_ (false),
     has_ftp_ext_ (true),
     new_connect_ (true)
   {
     INET_TRACE ("ACE_FTP_Session - ctor");
   }
Beispiel #10
0
 Session_T<ACE_SYNCH_USE>::Session_T ()
   : port_ (FTP_PORT),
     reactive_ (false),
     connection_ (0),
     sock_stream_ (0),
     ftp_timeout_ (DEFAULT_TIMEOUT),
     cannot_reconnect_ (false),
     has_ftp_ext_ (true),
     new_connect_ (true)
   {
     INET_TRACE ("ACE_FTP_Session - ctor");
   }
Beispiel #11
0
    bool Session_T<ACE_SYNCH_USE>::connect (bool use_reactor)
      {
        INET_TRACE ("ACE_FTP_Session::connect");

        typedef ACE_Connector<connection_type, ACE_SOCK_CONNECTOR> connector_type;

        this->close ();

        unsigned long f_reactor = use_reactor ? ACE_Synch_Options::USE_REACTOR : 0;
        ACE_Synch_Options sync_opt (ACE_Synch_Options::USE_TIMEOUT | f_reactor,
                                    this->ftp_timeout_);
        connector_type connector;

        connection_type* new_connection = 0;
        ACE_NEW_RETURN (new_connection,
                        connection_type(sync_opt),
                        false);
        if (connector.connect (new_connection,
                               ACE_INET_Addr (this->port_,
                                              this->host_.c_str ()),
                               ACE_Synch_Options (0,this->ftp_timeout_)) == -1)
          {
            INET_ERROR (1, (LM_ERROR, DLINFO
                            ACE_TEXT ("(%d) ACE_FTP_Session::connect - ")
                            ACE_TEXT ("failed to connect; host=%C, port=%d"),
                            ACE_OS::last_error (), this->host_.c_str (), this->port_));
            // as the connection was dynamically allocated
            // the connector causes it to be destroyed after
            // the connection failure
            return false;
          }

        this->connection_ = new_connection;
        this->connection_->reference_counting_policy ().value (
            ACE_Event_Handler::Reference_Counting_Policy::ENABLED);

        ACE_NEW_NORETURN (this->sock_stream_,
                          sock_stream_type (this->connection_));
        if (this->sock_stream_)
          {
            this->new_connect_ = true;
            this->cannot_reconnect_ = false;
            this->reactive_ = use_reactor;

            return true;
          }
        else
          {
            this->close ();
            return false;
          }
      }
Beispiel #12
0
    bool ConnectionCache::has_connection(const ConnectionKey& key)
      {
        INET_TRACE ("ConnectionCache::has_connection");

        ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX,
                                  guard_,
                                  this->lock_,
                                  false));

        ConnectionCacheValue cacheval;
        return (this->find_connection (key, cacheval) &&
                  cacheval.state () != ConnectionCacheValue::CST_CLOSED);
      }
Beispiel #13
0
    bool Session_T<ACE_SYNCH_USE>::send_interrupt ()
      {
        INET_TRACE ("ACE_FTP_Session::send_interrupt");

        if (this->is_connected ())
          {
            this->sock_stream_->put (ACE_Utils::truncate_cast<char> (int (INTERRUPT)));
            this->sock_stream_->sync ();
            return this->sock_stream_->good ();
          }

        return false;
      }
Beispiel #14
0
int
t_recv (long s, 
   char *   buf,
   int   len, 
   int   flag)
{
#ifdef SOCKDEBUG
   char logbuf[10];
#endif
   struct socket *   so;
   int   err;
   int   sendlen = len;

   so = LONG2SO(s);
#ifdef SOC_CHECK_ALWAYS
   SOC_CHECK(so);
#endif
   if ((so->so_state & SO_IO_OK) != SS_ISCONNECTED)
   {
      so->so_error = EPIPE;
#ifdef SOCKDEBUG
      sprintf(logbuf, "t_recv: %d", so->so_error);
      glog_with_type(LOG_TYPE_DEBUG, logbuf, 1);
#endif
      return SOCKET_ERROR;
   }
   so->so_error = 0;

   LOCK_NET_RESOURCE(NET_RESID);
   IN_PROFILER(PF_TCP, PF_ENTRY);        /* measure time in TCP */
   INET_TRACE (INETM_IO, ("INET:recv: so %x, len %d\n", so, len));
   err = soreceive(so, NULL, buf, &len, flag);
   IN_PROFILER(PF_TCP, PF_EXIT);        /* measure time in TCP */
   UNLOCK_NET_RESOURCE(NET_RESID);

   if(err)
   {
      so->so_error = err;
#ifdef SOCKDEBUG
      sprintf(logbuf, "t_recv: %d", so->so_error);
      glog_with_type(LOG_TYPE_DEBUG, logbuf, 1);
#endif
      return SOCKET_ERROR;
   }

   /* return bytes we sent - the amount we wanted to send minus
    * the amount left in the buffer.
    */
   return (sendlen - len);
}
Beispiel #15
0
    bool Session_T<ACE_SYNCH_USE>::connect_i (const ACE_Synch_Options& sync_opt)
      {
        INET_TRACE ("ACE_HTTP_Session::connect_i");

        typedef ACE_Connector<connection_type, ACE_SOCK_CONNECTOR> connector_type;

        connector_type connector;

        connection_type* new_connection = 0;
        ACE_NEW_RETURN (new_connection,
                        connection_type(sync_opt),
                        false);
        if (connector.connect (new_connection,
                               ACE_INET_Addr (this->port_,
                                              this->host_.c_str ()),
                               ACE_Synch_Options (0,this->http_timeout_)) == -1)
          {
            INET_ERROR (1, (LM_ERROR, DLINFO
                            ACE_TEXT ("(%d) ACE_HTTP_Session::connect_i - ")
                            ACE_TEXT ("failed to connect; host=%C, port=%d\n"),
                            ACE_OS::last_error (), this->host_.c_str (), this->port_));
            // as the connection was dynamically allocated
            // the connector causes it to be destroyed after
            // the connection failure
            return false;
          }

        this->connection_ = new_connection;
        this->connection_->reference_counting_policy ().value (
            ACE_Event_Handler::Reference_Counting_Policy::ENABLED);

        ACE_NEW_NORETURN (this->sock_stream_,
                          sock_stream_type (this->connection_));
        if (this->sock_stream_)
          {
            this->cannot_reconnect_ = false;
            this->reactive_ = sync_opt[ACE_Synch_Options::USE_REACTOR];

            // reset reconnect timer
            this->reconnect_timer_ = this->keep_alive_timeout_;
            this->reconnect_countdown_.start ();

            return true;
          }
        else
          {
            this->close ();
            return false;
          }
      }
Beispiel #16
0
    bool Session_T<ACE_SYNCH_USE>::connect (connection_type* connection)
      {
        INET_TRACE ("ACE_FTP_Session::connect(connection)");

        this->close ();

        if (connection->is_connected ())
          {
            ACE_INET_Addr remote;
            connection->peer ().get_remote_addr (remote);
            this->host_ = remote.get_host_name ();
            this->port_ = remote.get_port_number ();
          }
        else
          {
            typedef ACE_Connector<connection_type, ACE_SOCK_CONNECTOR> connector_type;

            connector_type connector;
            if (connector.connect (connection,
                                   ACE_INET_Addr (this->host_.c_str (),
                                                  this->port_)) == -1)
              {
                INET_ERROR (1, (LM_ERROR, DLINFO
                                ACE_TEXT ("(%d) ACE_FTP_Session::connect(connection) - ")
                                ACE_TEXT ("failed to connect; host=%C, port=%d"),
                                ACE_OS::last_error (), this->host_.c_str (), this->port_));
                return false;
              }
          }

        this->connection_ = connection;
        this->connection_->add_reference ();

        ACE_NEW_NORETURN (this->sock_stream_,
                          sock_stream_type (this->connection_));

        if (this->sock_stream_)
          {
            this->new_connect_ = true;
            this->cannot_reconnect_ = true;
            return true;
          }
        else
          {
            this->close ();
            return false;
          }
      }
Beispiel #17
0
    void Session_T<ACE_SYNCH_USE>::close ()
      {
        INET_TRACE ("ACE_FTP_Session::close");

        if (this->connection_)
          {
            if (this->sock_stream_)
              {
                delete this->sock_stream_;
                this->sock_stream_ = 0;
              }
            // this should be the last referece and removing it
            // causes the connection to be destroyed
            this->connection_->remove_reference ();
            this->connection_ = 0;
          }
      }
Beispiel #18
0
long
t_socket(int family, 
   int   type, 
   int   proto)
{
   struct socket *   so;

   INET_TRACE (INETM_SOCKET, ("SOCK:sock:family %d, typ %d, proto %d\n",
    family, type, proto));
   LOCK_NET_RESOURCE(NET_RESID);
   if ((so = socreate (family, type, proto)) == NULL) 
   {  /* can't really return error info since no socket.... */
      UNLOCK_NET_RESOURCE(NET_RESID);
      return SOCKET_ERROR;
   }
   SOC_RANGE(so);
   so->so_error = 0;
   UNLOCK_NET_RESOURCE(NET_RESID);
   return SO2LONG(so);
}
Beispiel #19
0
void
sofree(struct socket * so)
{
   INET_TRACE (INETM_SOCKET|INETM_CLOSE,
    ("INET: sofree, so %lx so_pcb %lx so_state %x so_head %lx\n",
    so, so->so_pcb, so->so_state, so->so_head));

   if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
      return;
   if (so->so_head) 
   {
      if (!soqremque(so, 0) && !soqremque(so, 1))
         panic("sofree");
      so->so_head = 0;
   }
   sbrelease(&so->so_snd);
   sorflush(so);
#ifdef SAVE_SOCK_ENDPOINTS
   if (so->so_endpoint)
      _socket_free_entry (so);
#endif   /* SAVE_SOCK_ENDPOINTS */

#ifdef IP_MULTICAST
   /* multicast opts? */
   if (so->inp_moptions)
	   ip_freemoptions(so->inp_moptions);
#endif   /* IP_MULTICAST */

   /* IP_TOS opts? */
   if (so->so_optsPack)
      SOCOPT_FREE(so->so_optsPack);
	   
   qdel(&soq, so);   /* Delete the socket entry from the queue */
   
   if (so_evtmap)  
      (*so_evtmap_delete) (so);
   
   SOC_FREE(so);
}
Beispiel #20
0
int
t_shutdown(long s, int   how)
{
   struct socket *so;
   int   err;

   so = LONG2SO(s);
   SOC_CHECK(so);
   so->so_error = 0;
   INET_TRACE (INETM_SOCKET, ("INET:shutdown so %x how %d\n", so, how));

   LOCK_NET_RESOURCE(NET_RESID);
   err = soshutdown(so, how);
   UNLOCK_NET_RESOURCE(NET_RESID);

   if (err != 0)
   {
      so->so_error = err;
      return SOCKET_ERROR;
   }
   return 0;
}
Beispiel #21
0
    void ConnectionCache::close_all_connections()
      {
        INET_TRACE ("ConnectionCache::close_all_connections");

        ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX,
                           guard_,
                           this->lock_));

        map_iter_type iter = this->cache_map_.end ();
        for (iter = this->cache_map_.begin ();
             iter != this->cache_map_.end ();
             ++iter)
          {
            if ((*iter).int_id_.state () == ConnectionCacheValue::CST_CLOSED)
              {
                connection_type* conn = (*iter).int_id_.connection ();
                (*iter).int_id_.connection (0);
                (*iter).int_id_.state (ConnectionCacheValue::CST_CLOSED);
                delete conn;
              }
          }
        this->cache_map_.unbind_all ();
      }
Beispiel #22
0
int
t_listen(long s, 
   int   backlog)
{
   struct socket *   so;
   int   err;

   so = LONG2SO(s);  /* convert long to socket */
   SOC_CHECK(so);
   so->so_error = 0;
   INET_TRACE (INETM_SOCKET, ("SOCK:listen:qlen %d\n", backlog));

   LOCK_NET_RESOURCE(NET_RESID);
   err = solisten (so, backlog);
   UNLOCK_NET_RESOURCE(NET_RESID);

   if (err != 0) 
   {
      so->so_error = err;
      return SOCKET_ERROR;
   }
   return 0;
}
Beispiel #23
0
    bool Session_T<ACE_SYNCH_USE>::send_request (Request& request)
      {
        INET_TRACE ("ACE_FTP_Session::send_request");

        if (!this->is_connected ())
          {
            if (this->cannot_reconnect_ || !this->connect(this->reactive_))
              {
                if (!this->cannot_reconnect_)
                  INET_ERROR (1, (LM_ERROR, DLINFO
                                  ACE_TEXT ("(%d) FTP_Session::send_request - ")
                                  ACE_TEXT ("reconnect failed\n"),
                                  ACE_OS::last_error ()));
                return ACE::IOS::Null::out_stream_;
              }
          }

        this->new_connect_ = false;

        request.write (*this->sock_stream_);

        return this->is_connected () && this->sock_stream_->good ();
      }
Beispiel #24
0
int
sodisconnect(struct socket * so)
{
   int   error;

   INET_TRACE (INETM_SOCKET|INETM_CLOSE,
    ("INET: sodisconnect, so %lx so_state %x\n", so, so->so_state));

   if ((so->so_state & SS_ISCONNECTED) == 0) 
   {
      error = ENOTCONN;
      goto bad;
   }
   if (so->so_state & SS_ISDISCONNECTING) 
   {
      error = EALREADY;
      goto bad;
   }
   so->so_req = PRU_DISCONNECT;
   error = (*so->so_proto->pr_usrreq)(so, (struct mbuf *)0, (struct mbuf *)0);

bad:
   return (error);
}
Beispiel #25
0
int
t_socketclose(long s)
{
   struct socket *   so;
   int   err;

   so = LONG2SO(s);
   SOC_CHECK(so);
   so->so_error = 0;
   INET_TRACE ((INETM_CLOSE|INETM_SOCKET), ("INET:close, so %lx\n",so));

   LOCK_NET_RESOURCE(NET_RESID);
   err = soclose(so);
   UNLOCK_NET_RESOURCE(NET_RESID);

   if (err != 0) 
   {
      /* do not do the following assignment since the socket structure
         addressed by so has been freed by this point, jharan 12-10-98 */
      /*      so->so_error = err;   */
      return SOCKET_ERROR;
   }
   return 0;
}
Beispiel #26
0
    bool ConnectionCache::claim_connection(const ConnectionKey& key,
                                           connection_type*& connection,
                                           const factory_type& connection_factory,
                                           bool wait)
      {
        INET_TRACE ("ConnectionCache::claim_connection");

        while (1)
          {
            bool create_connection = false;
            ConnectionCacheValue::State state = ConnectionCacheValue::CST_NONE;
            do
              {
                ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX,
                                          guard_,
                                          this->lock_,
                                          false));

                if (this->claim_existing_connection (key, connection, state))
                  {
                    INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("%P|%t) ConnectionCache::claim_connection - ")
                                             ACE_TEXT ("successfully claimed existing connection\n")));
                    return true;
                  }

                if ((state == ConnectionCacheValue::CST_BUSY ||
                        state == ConnectionCacheValue::CST_INIT) && !wait)
                  return false;

                if (state == ConnectionCacheValue::CST_CLOSED ||
                        state == ConnectionCacheValue::CST_NONE)
                  {
                    if (!this->set_connection (key, ConnectionCacheValue ()))
                      {
                        INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ")
                                                  ACE_TEXT ("failed to initialize connection entry")));
                        return false;
                      }

                    create_connection = true;
                  }
                else
                  {
                    INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ")
                                             ACE_TEXT ("waiting for connection to become available\n")));
                    // wait for connection to become ready/free
                    if (this->condition_.wait () != 0)
                      {
                        INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("(%P|%t) ConnectionCache::claim_connection - ")
                                                  ACE_TEXT ("error waiting for connection condition (%p)\n")));
                        return false;
                      }
                    INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ")
                                             ACE_TEXT ("awoken and retrying to claim connection\n")));
                  }
              }
            while (0);

            if (create_connection)
              {
                connection = connection_factory.create_connection (key);
                if (connection)
                  {
                    INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ")
                                             ACE_TEXT ("successfully created new connection\n")));

                    ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX,
                                              guard_,
                                              this->lock_,
                                              false));

                    ConnectionCacheValue cacheval (connection);
                    cacheval.state (ConnectionCacheValue::CST_BUSY);
                    return this->set_connection (key, cacheval);
                  }
                else
                  return false;
              }
          }
      }
Beispiel #27
0
long
t_accept(long s, 
   struct sockaddr * addr,
   int * addrlen)
{
#ifdef SOCKDEBUG
   char logbuf[10];
#endif
   struct socket *   so;
   struct mbuf *  nam;

   so = LONG2SO(s);
   SOC_CHECK(so);
   DOMAIN_CHECK(so, *addrlen);

   so->so_error = 0;
   INET_TRACE (INETM_SOCKET,
      ("INET:accept:so %x so_qlen %d so_state %x\n", so, so->so_qlen, so->so_state));
   if ((so->so_options & SO_ACCEPTCONN) == 0)
   {
      so->so_error = EINVAL;
#ifdef SOCKDEBUG
      sprintf(logbuf, "t_accept[%d]: %d", __LINE__, so->so_error);
      glog_with_type(LOG_TYPE_DEBUG, logbuf, 1);
#endif
      return SOCKET_ERROR;
   }
   if ((so->so_state & SS_NBIO) && so->so_qlen == 0)
   {
      so->so_error = EWOULDBLOCK;
#ifdef SOCKDEBUG
      sprintf(logbuf, "t_accept[%d]: %d", __LINE__, so->so_error);
      glog_with_type(LOG_TYPE_DEBUG, logbuf, 1);
#endif
      return SOCKET_ERROR;
   }
   LOCK_NET_RESOURCE(NET_RESID);
   while (so->so_qlen == 0 && so->so_error == 0)
   {
      if (so->so_state & SS_CANTRCVMORE)
      {
         so->so_error = ECONNABORTED;
         UNLOCK_NET_RESOURCE(NET_RESID);
         return SOCKET_ERROR;
      }
      tcp_sleep ((char *)&so->so_timeo);
   }
   if (so->so_error)
   {
#ifdef SOCKDEBUG
      sprintf(logbuf, "t_accept[%d]: %d", __LINE__, so->so_error);
      glog_with_type(LOG_TYPE_DEBUG, logbuf, 1);
#endif
      UNLOCK_NET_RESOURCE(NET_RESID);
      return SOCKET_ERROR;
   }
   nam = m_getwithdata (MT_SONAME, sizeof (struct sockaddr));
   if (nam == NULL) 
   {
      UNLOCK_NET_RESOURCE(NET_RESID);
      so->so_error = ENOMEM;
#ifdef SOCKDEBUG
      sprintf(logbuf, "t_accept[%d]: %d", __LINE__, so->so_error);
      glog_with_type(LOG_TYPE_DEBUG, logbuf, 1);
#endif
      return SOCKET_ERROR;
   }
   { 
      struct socket *aso = so->so_q;
      if (soqremque (aso, 1) == 0)
         panic("accept");
      so = aso;
   }
   (void)soaccept (so, nam);
#ifdef TRACE_DEBUG
   { struct sockaddr_in *sin;
      sin = mtod(nam, struct sockaddr_in *);
      INET_TRACE (INETM_SOCKET, ("INET:accept:done so %lx port %d addr %lx\n",
       so, sin->sin_port, sin->sin_addr.s_addr));
   }
#endif   /* TRACE_INET */
   /* return the addressing info in the passed structure */
   if (addr != NULL)
      MEMCPY(addr, nam->m_data, *addrlen);
   m_freem (nam);
   UNLOCK_NET_RESOURCE(NET_RESID);
   SOC_RANGE(so);
   return SO2LONG(so);
}
Beispiel #28
0
int
t_setsockopt(long s,
   int   level,
   int   name,
   void * arg,
   int arglen)
{
   struct socket *   so;
   int   err;

   so = LONG2SO(s);
   SOC_CHECK(so);
   USE_ARG(arglen);

   LOCK_NET_RESOURCE (NET_RESID);

   so->so_error = 0;
   INET_TRACE (INETM_SOCKET,
    ("INET: setsockopt: name %x val %x valsize %d\n",
    name, val));

   /* is it a level IP_OPTIONS call? */
   if (level != IP_OPTIONS)
   {
      if ((err = sosetopt (so, name, arg)) != 0) 
      {
         so->so_error = err;
         UNLOCK_NET_RESOURCE (NET_RESID);
         return SOCKET_ERROR;
      }
   }
   else
   {
   /* level 1 options are for the IP packet level.
    * the info is carried in the socket CB, then put 
    * into the PACKET.
    */
      if (!so->so_optsPack)
      {
         so->so_optsPack = (struct ip_socopts *) SOCOPT_ALLOC (sizeof(struct ip_socopts *));
         if (!so->so_optsPack) 
         {
            so->so_error = ENOMEM;
            UNLOCK_NET_RESOURCE (NET_RESID);
            return SOCKET_ERROR;
         }
      }
      
      if (name == IP_TTL_OPT)
         so->so_optsPack->ip_ttl = (u_char)(*(int *)arg);
      else
      if (name == IP_TOS)
         so->so_optsPack->ip_tos = (u_char)(*(int *)arg);
	   else
	   if (name == IP_SCOPEID)
            so->so_optsPack->ip_scopeid = (u_char)(*(u_int *)arg);
      else
      {
         UNLOCK_NET_RESOURCE (NET_RESID);
         return SOCKET_ERROR;
      }   
   }

   UNLOCK_NET_RESOURCE (NET_RESID);
   return 0;
}
Beispiel #29
0
static int
t_getname(long s, struct sockaddr * addr, int * addrlen, int opcode)
{
   struct socket *   so;
   struct mbuf *  m;
   int   err;

   so = LONG2SO(s);
   SOC_CHECK(so);

   so->so_error = 0;
   INET_TRACE (INETM_SOCKET, ("INET:get[sock|peer]name so %x\n", so));
   if((opcode == PRU_PEERADDR) && (so->so_state & SS_ISCONNECTED) == 0)
   {
      so->so_error = ENOTCONN;
      return SOCKET_ERROR;
   }
   LOCK_NET_RESOURCE(NET_RESID);
   m = m_getwithdata (MT_SONAME, sizeof (struct sockaddr));
   if (m == NULL) 
   {
      so->so_error = ENOMEM;
      UNLOCK_NET_RESOURCE(NET_RESID);
      return SOCKET_ERROR;
   }
   so->so_req = opcode;
   if ((err = (*so->so_proto->pr_usrreq)(so, 0, m)) != 0)
      goto bad;

#ifdef IP_V4
   if(so->so_domain == AF_INET)
   {
      if(*addrlen < sizeof(struct sockaddr_in))
      {
         dtrap();    /* programming error */
         m_freem(m);
         UNLOCK_NET_RESOURCE(NET_RESID);
         return EINVAL;
      }
      MEMCPY(addr, m->m_data, sizeof(struct sockaddr_in));
      *addrlen = sizeof(struct sockaddr_in);
   }
#endif   /* IP_V4 */
#ifdef IP_V6
   if(so->so_domain == AF_INET6)
   {
      if(*addrlen < sizeof(struct sockaddr_in6))
      {
         dtrap();    /* programming error */
         m_freem(m);
         UNLOCK_NET_RESOURCE(NET_RESID);
         return EINVAL;
      }
      MEMCPY(addr, m->m_data, sizeof(struct sockaddr_in6));
      *addrlen = sizeof(struct sockaddr_in6);
   }
#endif   /* IP_V6 */


bad:
   m_freem(m);
   UNLOCK_NET_RESOURCE(NET_RESID);
   if (err) 
   {
      so->so_error = err;
      return SOCKET_ERROR;
   }
   return 0;
}
Beispiel #30
0
int
t_connect(long s, 
   struct sockaddr * addr,
   int   addrlen)
{
   struct socket *   so;
   struct mbuf *  nam;

   so = LONG2SO(s);
   SOC_CHECK(so);
   DOMAIN_CHECK(so, addrlen);

#ifdef NB_CONNECT
   /* need to test non blocking connect bits in case this is a 
      poll of a previous request */
   if (so->so_state & SS_NBIO)
   {
      if (so->so_state & SS_ISCONNECTING) /* still trying */
      {
         so->so_error = EINPROGRESS;
         return SOCKET_ERROR;
      }
      if (so->so_state & SS_ISCONNECTED)  /* connected OK */
      {
         so->so_error = 0;
         return 0;
      }
      if (so->so_state & SS_WASCONNECTING)
      {
         so->so_state &= ~SS_WASCONNECTING;
         if (so->so_error) /* connect error - maybe timeout */
            return SOCKET_ERROR;
      }
   }
#endif   /*  NB_CONNECT */

   so->so_error = 0;

   if ((nam = sockargs (addr, addrlen, MT_SONAME))
       == NULL)
   {
      so->so_error = ENOMEM;
      return SOCKET_ERROR;
   }

#ifdef TRACE_DEBUG
   { struct sockaddr_in *sin = (struct sockaddr_in *)uap->sap;
      INET_TRACE (INETM_SOCKET, ("INET: connect, port %d addr %lx\n",
       sin->sin_port, sin->sin_addr.s_addr));
   }
#endif   /* TRACE_DEBUG */

   LOCK_NET_RESOURCE(NET_RESID);
   if ((so->so_error = soconnect (so, nam)) != 0)
      goto bad;

#ifdef NB_CONNECT
   /* need to test non blocking connect bits after soconnect() call */
   if ((so->so_state & SS_NBIO)&& (so->so_state & SS_ISCONNECTING))
   {
      so->so_error = EINPROGRESS;
      goto bad;
   }
#endif   /*  NB_CONNECT */
   INET_TRACE (INETM_SOCKET, ("INET: connect, so %x so_state %x so_error %d\n",
    so, so->so_state, so->so_error));

   while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) 
   {
      tcp_sleep ((char *)&so->so_timeo);
   }
bad:
   if (so->so_error != EINPROGRESS)
      so->so_state &= ~(SS_ISCONNECTING|SS_WASCONNECTING);
   m_freem (nam);

   UNLOCK_NET_RESOURCE(NET_RESID);
   if (so->so_error)
   {
/*      printf("t_connect(): so_error = %d\n", so->so_error);*/
      return SOCKET_ERROR;

   }
      return 0;
}