--- manager.c 23 Oct 2004 12:19:47 -0000 1.77 +++ manager.c 28 Oct 2004 13:40:07 -0000 @@ -38,6 +38,7 @@ #include #include #include +#include #include struct fast_originate_helper @@ -1236,58 +1237,36 @@ return NULL; } -static void *accept_thread(void *ignore) + +static int +manager_incoming(int server_fd, int new_fd, struct sockaddr_in * sin, void * data) { - int as; - struct sockaddr_in sin; - int sinlen; - struct mansession *s; - struct protoent *p; - int arg = 1; - int flags; - pthread_attr_t attr; + struct mansession * s; + char addr[INET_ADDRSTRLEN]; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ast_log(LOG_DEBUG, "Manager got incoming socket from %s:%d\n", ast_inet_ntoa(addr, sizeof(addr), sin->sin_addr), ntohs(sin->sin_port)); - for (;;) { - sinlen = sizeof(sin); - as = accept(asock, (struct sockaddr *)&sin, &sinlen); - if (as < 0) { - ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno)); - continue; - } - p = getprotobyname("tcp"); - if( p ) { - if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { - ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\n", strerror(errno)); - } - } - s = malloc(sizeof(struct mansession)); - if (!s) { - ast_log(LOG_WARNING, "Failed to allocate management session: %s\n", strerror(errno)); - continue; - } - memset(s, 0, sizeof(struct mansession)); - memcpy(&s->sin, &sin, sizeof(sin)); - - if(! block_sockets) { - /* For safety, make sure socket is non-blocking */ - flags = fcntl(as, F_GETFL); - fcntl(as, F_SETFL, flags | O_NONBLOCK); - } - ast_mutex_init(&s->lock); - s->fd = as; - s->send_events = -1; - ast_mutex_lock(&sessionlock); - s->next = sessions; - sessions = s; - ast_mutex_unlock(&sessionlock); - if (ast_pthread_create(&t, &attr, session_do, s)) - destroy_session(s); - } - pthread_attr_destroy(&attr); - return NULL; + s = ast_snew0(struct mansession, 1); + + if (!s) { + ast_log(LOG_WARNING, "Failed to allocate management session: %s\n", strerror(errno)); + return -1; + } + + memcpy(&s->sin, sin, sizeof(*sin)); + + ast_mutex_init(&s->lock); + s->fd = new_fd; + s->send_events = -1; + ast_mutex_lock(&sessionlock); + s->next = sessions; + sessions = s; + ast_mutex_unlock(&sessionlock); + + if (ast_pthread_create(&t, NULL, session_do, s)) + destroy_session(s); + + return 0; } int manager_event(int category, char *event, char *fmt, ...) @@ -1415,7 +1394,7 @@ char *val; int oldportno = portno; static struct sockaddr_in ba; - int x = 1; + if (!registered) { /* Register default actions */ ast_manager_register2("Ping", 0, action_ping, "Ping", mandescr_ping); @@ -1489,34 +1468,21 @@ #endif } ast_destroy(cfg); + + /* If not enabled, do nothing */ - if (!enabled) { + + if (!enabled) return 0; - } - if (asock < 0) { - asock = socket(AF_INET, SOCK_STREAM, 0); - if (asock < 0) { - ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); - return -1; - } - setsockopt(asock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); - if (bind(asock, (struct sockaddr *)&ba, sizeof(ba))) { - ast_log(LOG_WARNING, "Unable to bind socket: %s\n", strerror(errno)); - close(asock); - asock = -1; - return -1; - } - if (listen(asock, 2)) { - ast_log(LOG_WARNING, "Unable to listen on socket: %s\n", strerror(errno)); - close(asock); - asock = -1; - return -1; - } - if (option_verbose) - ast_verbose("Asterisk Management interface listening on port %d\n", portno); - ast_pthread_create(&t, NULL, accept_thread, NULL); - } + + asock = ast_nbio_listen_tcp(&ba, AST_NBIO_FLAG_NODELAY, "Manager", NBIO_CONNECTION_CB(manager_incoming), NULL); + + if (asock == -1) + ast_log(LOG_ERROR, "Failed to create socket for manager\n"); + else + ast_verbose("Asterisk Management interface listening on port %d\n", portno); + return 0; }