/* This function adds the specified listener's file descriptor to the polling * lists if it is in the LI_LISTEN state. The listener enters LI_READY or * LI_FULL state depending on its number of connections. */ void enable_listener(struct listener *listener) { if (listener->state == LI_LISTEN) { if (listener->nbconn < listener->maxconn) { EV_FD_SET(listener->fd, DIR_RD); listener->state = LI_READY; } else { listener->state = LI_FULL; } } }
/* * This function reactivates listening. This can be used after a call to * sig_pause(), for example when a new instance has failed starting up. * It is designed to be called upon reception of a SIGTTIN. */ void listen_proxies(void) { struct proxy *p; struct listener *l; p = proxy; tv_update_date(0,1); /* else, the old time before select will be used */ while (p) { if (p->state == PR_STPAUSED) { Warning("Enabling %s %s.\n", proxy_cap_str(p->cap), p->id); send_log(p, LOG_WARNING, "Enabling %s %s.\n", proxy_cap_str(p->cap), p->id); for (l = p->listen; l != NULL; l = l->next) { if (listen(l->fd, p->backlog ? p->backlog : p->maxconn) == 0) { if (actconn < global.maxconn && p->feconn < p->maxconn) { EV_FD_SET(l->fd, DIR_RD); p->state = PR_STRUN; } else p->state = PR_STIDLE; } else { int port; if (l->addr.ss_family == AF_INET6) { port = ntohs(((struct sockaddr_in6 *)(&l->addr))->sin6_port); Warning("Port %d busy while trying to enable %s %s.\n", port, proxy_cap_str(p->cap), p->id); send_log(p, LOG_WARNING, "Port %d busy while trying to enable %s %s.\n", port, proxy_cap_str(p->cap), p->id); } else if (l->addr.ss_family == AF_INET) { port = ntohs(((struct sockaddr_in *)(&l->addr))->sin_port); Warning("Port %d busy while trying to enable %s %s.\n", port, proxy_cap_str(p->cap), p->id); send_log(p, LOG_WARNING, "Port %d busy while trying to enable %s %s.\n", port, proxy_cap_str(p->cap), p->id); } else { Warning("Bind on socket %d busy while trying to enable %s %s.\n", l->luid, proxy_cap_str(p->cap), p->id); send_log(p, LOG_WARNING, "Bind on socket %d busy while trying to enable %s %s.\n", l->luid, proxy_cap_str(p->cap), p->id); } /* Another port might have been enabled. Let's stop everything. */ pause_proxy(p); break; } } } p = p->next; } }
/* This function tries to resume a temporarily disabled listener. Paused, full, * limited and disabled listeners are handled, which means that this function * may replace enable_listener(). The resulting state will either be LI_READY * or LI_FULL. 0 is returned in case of failure to resume (eg: dead socket). */ int resume_listener(struct listener *l) { if (l->state < LI_PAUSED) return 0; if (l->state == LI_PAUSED && listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0) return 0; if (l->state == LI_READY) return 1; if (l->state == LI_LIMITED) LIST_DEL(&l->wait_queue); if (l->nbconn >= l->maxconn) { l->state = LI_FULL; return 1; } EV_FD_SET(l->fd, DIR_RD); l->state = LI_READY; return 1; }