struct evconnlistener *init_socket_activated(void) { evutil_socket_t fd = SD_LISTEN_FDS_START + 0; evutil_make_socket_nonblocking(fd); return evconnlistener_new(base, cb_new_connection, NULL, 0, 0 /* Set to 0 if the socket is already listening*/, fd); }
static void regress_listener_error(void *arg) { struct basic_test_data *data = arg; struct event_base *base = data->base; struct evconnlistener *listener = NULL; int count = 1; unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE; if (data->setup_data && strstr((char*)data->setup_data, "ts")) { flags |= LEV_OPT_THREADSAFE; } /* send, so that pair[0] will look 'readable'*/ tt_int_op(send(data->pair[1], "hello", 5, 0), >, 0); /* Start a listener with a bogus socket. */ listener = evconnlistener_new(base, acceptcb, &count, flags, 0, data->pair[0]); tt_assert(listener); evconnlistener_set_error_cb(listener, errorcb); tt_assert(listener); event_base_dispatch(base); tt_int_op(count,==,1000); /* set by error cb */ end: if (listener) evconnlistener_free(listener); }
static int create_server_listener(tls_listener_relay_server_type* server) { FUNCSTART; if(!server) return -1; evutil_socket_t tls_listen_fd = -1; tls_listen_fd = socket(server->addr.ss.ss_family, SOCK_STREAM, 0); if (tls_listen_fd < 0) { perror("socket"); return -1; } if(sock_bind_to_device(tls_listen_fd, (unsigned char*)server->ifname)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to device %s\n",server->ifname); } if(addr_bind(tls_listen_fd,&server->addr)<0) { perror("Cannot bind local socket to addr"); char saddr[129]; addr_to_string(&server->addr,(u08bits*)saddr); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind TCP/TLS listener socket to addr %s\n",saddr); socket_closesocket(tls_listen_fd); return -1; } socket_tcp_set_keepalive(tls_listen_fd); socket_set_nonblocking(tls_listen_fd); server->l = evconnlistener_new(server->e->event_base, server_input_handler, server, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 1024, tls_listen_fd); if(!(server->l)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot create TLS listener\n"); socket_closesocket(tls_listen_fd); return -1; } if(addr_get_from_sock(tls_listen_fd, &(server->addr))) { perror("Cannot get local socket addr"); socket_closesocket(tls_listen_fd); return -1; } if(!no_tcp && !no_tls) addr_debug_print(server->verbose, &server->addr,"TCP/TLS listener opened on "); else if(!no_tls) addr_debug_print(server->verbose, &server->addr,"TLS listener opened on "); else if(!no_tcp) addr_debug_print(server->verbose, &server->addr,"TCP listener opened on "); FUNCEND; return 0; }
struct evconnlistener * evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb, void *ptr, unsigned flags, int backlog, const struct sockaddr *sa, int socklen) { struct evconnlistener *listener; evutil_socket_t fd; int on = 1; int family = sa ? sa->sa_family : AF_UNSPEC; if (backlog == 0) return NULL; fd = socket(family, SOCK_STREAM, 0); if (fd == -1) return NULL; if (evutil_make_socket_nonblocking(fd) < 0) { evutil_closesocket(fd); return NULL; } if (flags & LEV_OPT_CLOSE_ON_EXEC) { if (evutil_make_socket_closeonexec(fd) < 0) { evutil_closesocket(fd); return NULL; } } if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&on, sizeof(on))<0) { evutil_closesocket(fd); return NULL; } if (flags & LEV_OPT_REUSEABLE) { if (evutil_make_listen_socket_reuseable(fd) < 0) { evutil_closesocket(fd); return NULL; } } if (sa) { if (bind(fd, sa, socklen)<0) { evutil_closesocket(fd); return NULL; } } listener = evconnlistener_new(base, cb, ptr, flags, backlog, fd); if (!listener) { evutil_closesocket(fd); return NULL; } return listener; }
struct evconnlistener * evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb, void *ptr, unsigned flags, int backlog, const struct sockaddr *sa, int socklen) { struct evconnlistener *listener; evutil_socket_t fd; int on = 1; int family = sa ? sa->sa_family : AF_UNSPEC; int socktype = SOCK_STREAM | EVUTIL_SOCK_NONBLOCK; if (backlog == 0) return NULL; if (flags & LEV_OPT_CLOSE_ON_EXEC) socktype |= EVUTIL_SOCK_CLOEXEC; fd = evutil_socket_(family, socktype, 0); if (fd == -1) return NULL; if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&on, sizeof(on))<0) goto err; if (flags & LEV_OPT_REUSEABLE) { if (evutil_make_listen_socket_reuseable(fd) < 0) goto err; } if (flags & LEV_OPT_REUSEABLE_PORT) { if (evutil_make_listen_socket_reuseable_port(fd) < 0) goto err; } if (flags & LEV_OPT_DEFERRED_ACCEPT) { if (evutil_make_tcp_listen_socket_deferred(fd) < 0) goto err; } if (sa) { if (bind(fd, sa, socklen)<0) goto err; } listener = evconnlistener_new(base, cb, ptr, flags, backlog, fd); if (!listener) goto err; return listener; err: evutil_closesocket(fd); return NULL; }
struct evwsconnlistener *evwsconnlistener_new(struct event_base *base, evwsconnlistener_cb cb, void *user_data, unsigned flags, int backlog, const char* subprotocols[], SSL_CTX* server_ctx, evutil_socket_t fd) { struct evwsconnlistener *levws = (struct evwsconnlistener *)malloc(sizeof(struct evwsconnlistener)); if (!levws) return NULL; levws->lev = evconnlistener_new(base, lev_cb, levws, flags, backlog, fd); if (!levws->lev) { free(levws); return NULL; } levws->cb = cb; levws->errorcb = NULL; levws->user_data = user_data; levws->supported_subprotocols = subprotocols; levws->server_ctx = server_ctx; levws->head = NULL; return levws; }
bool cServerHandleImpl::Listen(UInt16 a_Port) { // Make sure the cNetwork internals are innitialized: cNetworkSingleton::Get(); // Set up the main socket: // It should listen on IPv6 with IPv4 fallback, when available; IPv4 when IPv6 is not available. bool NeedsTwoSockets = false; int err; evutil_socket_t MainSock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); if (!IsValidSocket(MainSock)) { // Failed to create IPv6 socket, create an IPv4 one instead: err = EVUTIL_SOCKET_ERROR(); LOGD("Failed to create IPv6 MainSock: %d (%s)", err, evutil_socket_error_to_string(err)); MainSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (!IsValidSocket(MainSock)) { m_ErrorCode = EVUTIL_SOCKET_ERROR(); Printf(m_ErrorMsg, "Cannot create socket for port %d: %s", a_Port, evutil_socket_error_to_string(m_ErrorCode)); return false; } // Allow the port to be reused right after the socket closes: if (evutil_make_listen_socket_reuseable(MainSock) != 0) { m_ErrorCode = EVUTIL_SOCKET_ERROR(); Printf(m_ErrorMsg, "Port %d cannot be made reusable: %d (%s). Restarting the server might not work.", a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode) ); LOG("%s", m_ErrorMsg.c_str()); } // Bind to all interfaces: sockaddr_in name; memset(&name, 0, sizeof(name)); name.sin_family = AF_INET; name.sin_port = ntohs(a_Port); if (bind(MainSock, reinterpret_cast<const sockaddr *>(&name), sizeof(name)) != 0) { m_ErrorCode = EVUTIL_SOCKET_ERROR(); Printf(m_ErrorMsg, "Cannot bind IPv4 socket to port %d: %s", a_Port, evutil_socket_error_to_string(m_ErrorCode)); evutil_closesocket(MainSock); return false; } } else { // IPv6 socket created, switch it into "dualstack" mode: UInt32 Zero = 0; #ifdef _WIN32 // WinXP doesn't support this feature, so if the setting fails, create another socket later on: int res = setsockopt(MainSock, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<const char *>(&Zero), sizeof(Zero)); err = EVUTIL_SOCKET_ERROR(); NeedsTwoSockets = ((res == SOCKET_ERROR) && (err == WSAENOPROTOOPT)); #else setsockopt(MainSock, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<const char *>(&Zero), sizeof(Zero)); #endif // Allow the port to be reused right after the socket closes: if (evutil_make_listen_socket_reuseable(MainSock) != 0) { m_ErrorCode = EVUTIL_SOCKET_ERROR(); Printf(m_ErrorMsg, "Port %d cannot be made reusable: %d (%s). Restarting the server might not work.", a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode) ); LOG("%s", m_ErrorMsg.c_str()); } // Bind to all interfaces: sockaddr_in6 name; memset(&name, 0, sizeof(name)); name.sin6_family = AF_INET6; name.sin6_port = ntohs(a_Port); if (bind(MainSock, reinterpret_cast<const sockaddr *>(&name), sizeof(name)) != 0) { m_ErrorCode = EVUTIL_SOCKET_ERROR(); Printf(m_ErrorMsg, "Cannot bind IPv6 socket to port %d: %d (%s)", a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode)); evutil_closesocket(MainSock); return false; } } if (evutil_make_socket_nonblocking(MainSock) != 0) { m_ErrorCode = EVUTIL_SOCKET_ERROR(); Printf(m_ErrorMsg, "Cannot make socket on port %d non-blocking: %d (%s)", a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode)); evutil_closesocket(MainSock); return false; } if (listen(MainSock, 0) != 0) { m_ErrorCode = EVUTIL_SOCKET_ERROR(); Printf(m_ErrorMsg, "Cannot listen on port %d: %d (%s)", a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode)); evutil_closesocket(MainSock); return false; } m_ConnListener = evconnlistener_new(cNetworkSingleton::Get().GetEventBase(), Callback, this, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 0, MainSock); m_IsListening = true; if (!NeedsTwoSockets) { return true; } // If a secondary socket is required (WinXP dual-stack), create it here: LOGD("Creating a second socket for IPv4"); evutil_socket_t SecondSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (!IsValidSocket(SecondSock)) { err = EVUTIL_SOCKET_ERROR(); LOGD("socket(AF_INET, ...) failed for secondary socket: %d, %s", err, evutil_socket_error_to_string(err)); return true; // Report as success, the primary socket is working } // Allow the port to be reused right after the socket closes: if (evutil_make_listen_socket_reuseable(SecondSock) != 0) { m_ErrorCode = EVUTIL_SOCKET_ERROR(); Printf(m_ErrorMsg, "Port %d cannot be made reusable (second socket): %d (%s). Restarting the server might not work.", a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode) ); LOG("%s", m_ErrorMsg.c_str()); } // Make the secondary socket nonblocking: if (evutil_make_socket_nonblocking(SecondSock) != 0) { err = EVUTIL_SOCKET_ERROR(); LOGD("evutil_make_socket_nonblocking() failed for secondary socket: %d, %s", err, evutil_socket_error_to_string(err)); evutil_closesocket(SecondSock); return true; // Report as success, the primary socket is working } // Bind to all IPv4 interfaces: sockaddr_in name; memset(&name, 0, sizeof(name)); name.sin_family = AF_INET; name.sin_port = ntohs(a_Port); if (bind(SecondSock, reinterpret_cast<const sockaddr *>(&name), sizeof(name)) != 0) { err = EVUTIL_SOCKET_ERROR(); LOGD("Cannot bind secondary socket to port %d: %d (%s)", a_Port, err, evutil_socket_error_to_string(err)); evutil_closesocket(SecondSock); return true; // Report as success, the primary socket is working } if (listen(SecondSock, 0) != 0) { err = EVUTIL_SOCKET_ERROR(); LOGD("Cannot listen on secondary socket on port %d: %d (%s)", a_Port, err, evutil_socket_error_to_string(err)); evutil_closesocket(SecondSock); return true; // Report as success, the primary socket is working } m_SecondaryConnListener = evconnlistener_new(cNetworkSingleton::Get().GetEventBase(), Callback, this, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 0, SecondSock); return true; }
int main(int argc, char *argv[]) { struct event_base *base; struct evconnlistener *listener; struct sockaddr_in sin; base = event_base_new(); if (!base) { fprintf(stderr, "Could not initialize libevent!\n"); return 1; } memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(PORT); // create server socket manually // to make this code works with other frameworks which // we don't open socket by ourselves. int reuseaddr_on = 1; int server_socket; server_socket = socket(AF_INET, SOCK_STREAM , 0); if (server_socket < 0) { fprintf(stderr, "Could not open socket!\n"); return 1; } if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR | SO_KEEPALIVE, &reuseaddr_on, sizeof(reuseaddr_on)) < 0) { fprintf(stderr, "setsockopt failed"); goto err; } if (evutil_make_socket_nonblocking(server_socket) < 0) { fprintf(stderr, "set nonblocking failed"); goto err; } if (bind(server_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0) { fprintf(stderr, "bind failed\n"); goto err; } // add libevent connection listener listener = evconnlistener_new(base, listener_cb, (void *)base, LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1, server_socket); if (!listener) { fprintf(stderr, "Could not create a listener!\n"); goto err; } // signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base); // if (!signal_event || event_add(signal_event, NULL)<0) { // fprintf(stderr, "Could not create/add a signal event!\n"); // return 1; // } event_base_dispatch(base); evconnlistener_free(listener); // event_free(signal_event); event_base_free(base); printf("done\n"); return 0; err: evutil_closesocket(server_socket); return 1; }