// static LLSocket::ptr_t LLSocket::create(apr_socket_t* socket, apr_pool_t* pool) { LLMemType m1(LLMemType::MTYPE_IO_TCP); LLSocket::ptr_t rv; if(!socket) { return rv; } rv = ptr_t(new LLSocket(socket, pool)); rv->mPort = PORT_EPHEMERAL; rv->setOptions(); return rv; }
// static LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port) { LLMemType m1(LLMemType::MTYPE_IO_TCP); LLSocket::ptr_t rv; apr_socket_t* socket = NULL; apr_pool_t* new_pool = NULL; apr_status_t status = APR_EGENERAL; // create a pool for the socket status = apr_pool_create(&new_pool, pool); if(ll_apr_warn_status(status)) { if(new_pool) apr_pool_destroy(new_pool); return rv; } if(STREAM_TCP == type) { status = apr_socket_create( &socket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, new_pool); } else if(DATAGRAM_UDP == type) { status = apr_socket_create( &socket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, new_pool); } else { if(new_pool) apr_pool_destroy(new_pool); return rv; } if(ll_apr_warn_status(status)) { if(new_pool) apr_pool_destroy(new_pool); return rv; } rv = ptr_t(new LLSocket(socket, new_pool)); if(port > 0) { apr_sockaddr_t* sa = NULL; status = apr_sockaddr_info_get( &sa, APR_ANYADDR, APR_UNSPEC, port, 0, new_pool); if(ll_apr_warn_status(status)) { rv.reset(); return rv; } // This allows us to reuse the address on quick down/up. This // is unlikely to create problems. ll_apr_warn_status(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1)); status = apr_socket_bind(socket, sa); if(ll_apr_warn_status(status)) { rv.reset(); return rv; } lldebugs << "Bound " << ((DATAGRAM_UDP == type) ? "udp" : "tcp") << " socket to port: " << sa->port << llendl; if(STREAM_TCP == type) { // If it's a stream based socket, we need to tell the OS // to keep a queue of incoming connections for ACCEPT. lldebugs << "Setting listen state for socket." << llendl; status = apr_socket_listen( socket, LL_DEFAULT_LISTEN_BACKLOG); if(ll_apr_warn_status(status)) { rv.reset(); return rv; } } } else { // we need to indicate that we have an ephemeral port if the // previous calls were successful. It will port = PORT_EPHEMERAL; } rv->mPort = port; rv->setOptions(); return rv; }