diff --git a/include/proto/protocols.h b/include/proto/protocols.h index 7b9e1dd9a..353e4c441 100644 --- a/include/proto/protocols.h +++ b/include/proto/protocols.h @@ -51,6 +51,13 @@ int enable_all_listeners(struct protocol *proto); */ int disable_all_listeners(struct protocol *proto); +/* This function closes the listening socket for the specified listener, + * provided that it's already in a listening state. The listener enters the + * LI_ASSIGNED state. It always returns ERR_NONE. This function is intended + * to be used as a generic function for standard protocols. + */ +int unbind_listener(struct listener *listener); + /* Registers the protocol */ void protocol_register(struct protocol *proto); diff --git a/src/protocols.c b/src/protocols.c index 2412d0e40..3e118b822 100644 --- a/src/protocols.c +++ b/src/protocols.c @@ -20,6 +20,8 @@ #include +#include + /* List head of all registered protocols */ static struct list protocols = LIST_HEAD_INIT(protocols); @@ -81,6 +83,23 @@ int disable_all_listeners(struct protocol *proto) return ERR_NONE; } +/* This function closes the listening socket for the specified listener, + * provided that it's already in a listening state. The listener enters the + * LI_ASSIGNED state. It always returns ERR_NONE. This function is intended + * to be used as a generic function for standard protocols. + */ +int unbind_listener(struct listener *listener) +{ + if (listener->state == LI_READY) + EV_FD_CLR(listener->fd, DIR_RD); + + if (listener->state >= LI_LISTEN) { + fd_delete(listener->fd); + listener->state = LI_ASSIGNED; + } + return ERR_NONE; +} + /* Registers the protocol */ void protocol_register(struct protocol *proto) {