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; }
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"); }
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; }
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; } }
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; }
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; }
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"); }
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_); }
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"); }
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"); }
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; } }
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); }
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; }
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); }
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; } }
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; } }
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; } }
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); }
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); }
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; }
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 (); }
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; }
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 (); }
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); }
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; }
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; } } }
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); }
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; }
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; }
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; }