Skip to content

Commit

Permalink
modules: Improve Asterisk queues integration.
Browse files Browse the repository at this point in the history
* mod_asterisk_ami: Fix deadlock caused by not
  writing to alertpipe when unregistering/registering
  AMI callbacks.
* mod_asterisk_ami: Fix reconnects not working.
* mod_asterisk_queues: Keep track of whether stats for
  queues or agents are stale and update them as needed.
* mod_mail_trash: Decrease frequency of garbage collection.
* socket.c/fd.c: Store caller location for more useful fd location.
  • Loading branch information
InterLinked1 committed Nov 24, 2023
1 parent eef3663 commit f3ad32d
Show file tree
Hide file tree
Showing 13 changed files with 250 additions and 65 deletions.
15 changes: 13 additions & 2 deletions bbs/alertpipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,20 @@ int bbs_alertpipe_read(int alert_pipe[2])
return 0;
}

int bbs_alertpipe_create(int alert_pipe[2])
int __bbs_alertpipe_create(int alert_pipe[2], const char *file, int line, const char *func)
{
/* Prefer eventfd to pipe since it's more efficient (only 1 fd needed, rather than 2) */
int fd = eventfd(0, EFD_NONBLOCK | EFD_SEMAPHORE);
int fd;

#if defined(DEBUG_FD_LEAKS) && DEBUG_FD_LEAKS == 1
fd = __bbs_eventfd(0, EFD_NONBLOCK | EFD_SEMAPHORE, file, line, func);
#else
UNUSED(file);
UNUSED(line);
UNUSED(func);
fd = eventfd(0, EFD_NONBLOCK | EFD_SEMAPHORE);
#endif

if (fd > -1) {
alert_pipe[0] = alert_pipe[1] = fd;
return 0;
Expand Down Expand Up @@ -101,6 +111,7 @@ int bbs_alertpipe_poll(int alert_pipe[2], int ms)
if (pfd.revents) {
return 1;
}
break;
}
return res;
}
22 changes: 11 additions & 11 deletions bbs/fd.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ static int bbs_fd_dump(int fd)
LOG_FAILURE(); \
}

int __fdleak_open(const char *file, int line, const char *func, const char *path, int flags, ...)
int __bbs_open(const char *file, int line, const char *func, const char *path, int flags, ...)
{
int res;
va_list ap;
Expand Down Expand Up @@ -236,15 +236,15 @@ int __fdleak_open(const char *file, int line, const char *func, const char *path
return res;
}

int __fdleak_accept(int socket, struct sockaddr *address, socklen_t *address_len,
int __bbs_accept(int socket, struct sockaddr *address, socklen_t *address_len,
const char *file, int line, const char *func)
{
int res = accept(socket, address, address_len);
STORE_COMMON_HELPER(res, "accept", "{%d}", socket);
return res;
}

int __fdleak_pipe(int *fds, const char *file, int line, const char *func)
int __bbs_pipe(int *fds, const char *file, int line, const char *func)
{
int i, res = pipe(fds);
if (res) {
Expand All @@ -256,7 +256,7 @@ int __fdleak_pipe(int *fds, const char *file, int line, const char *func)
return 0;
}

int __fdleak_socketpair(int domain, int type, int protocol, int sv[2],
int __bbs_socketpair(int domain, int type, int protocol, int sv[2],
const char *file, int line, const char *func)
{
int i, res = socketpair(domain, type, protocol, sv);
Expand All @@ -269,14 +269,14 @@ int __fdleak_socketpair(int domain, int type, int protocol, int sv[2],
return 0;
}

int __fdleak_eventfd(unsigned int initval, int flags, const char *file, int line, const char *func)
int __bbs_eventfd(unsigned int initval, int flags, const char *file, int line, const char *func)
{
int res = eventfd(initval, flags);
STORE_COMMON_HELPER(res, "eventfd", "{%d}", res);
return res;
}

int __fdleak_socket(int domain, int type, int protocol, const char *file, int line, const char *func)
int __bbs_socket(int domain, int type, int protocol, const char *file, int line, const char *func)
{
char sdomain[20], stype[20];
const char *sproto = NULL;
Expand Down Expand Up @@ -322,7 +322,7 @@ int __fdleak_socket(int domain, int type, int protocol, const char *file, int li
return res;
}

int __fdleak_close(int fd, const char *file, int line, const char *func)
int __bbs_close(int fd, const char *file, int line, const char *func)
{
int res;

Expand All @@ -339,7 +339,7 @@ int __fdleak_close(int fd, const char *file, int line, const char *func)
return res;
}

FILE *__fdleak_fopen(const char *path, const char *mode, const char *file, int line, const char *func)
FILE *__bbs_fopen(const char *path, const char *mode, const char *file, int line, const char *func)
{
FILE *res = fopen(path, mode);
int fd;
Expand All @@ -351,7 +351,7 @@ FILE *__fdleak_fopen(const char *path, const char *mode, const char *file, int l
return res;
}

int __fdleak_fclose(FILE *ptr)
int __bbs_fclose(FILE *ptr)
{
int fd, res;

Expand All @@ -364,7 +364,7 @@ int __fdleak_fclose(FILE *ptr)
return res;
}

int __fdleak_dup2(int oldfd, int newfd, const char *file, int line, const char *func)
int __bbs_dup2(int oldfd, int newfd, const char *file, int line, const char *func)
{
int res = dup2(oldfd, newfd);
/* On success, newfd will be closed automatically if it was already
Expand All @@ -374,7 +374,7 @@ int __fdleak_dup2(int oldfd, int newfd, const char *file, int line, const char *
return res;
}

int __fdleak_dup(int oldfd, const char *file, int line, const char *func)
int __bbs_dup(int oldfd, const char *file, int line, const char *func)
{
int res = dup(oldfd);
STORE_COMMON_HELPER(res, "dup2", "%d", oldfd);
Expand Down
29 changes: 26 additions & 3 deletions bbs/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@

extern int option_rebind;

int bbs_make_unix_socket(int *sock, const char *sockfile, const char *perm, uid_t uid, gid_t gid)
int __bbs_make_unix_socket(int *sock, const char *sockfile, const char *perm, uid_t uid, gid_t gid, const char *file, int line, const char *func)
{
struct sockaddr_un sunaddr; /* UNIX socket */
int res;
Expand All @@ -64,7 +64,14 @@ int bbs_make_unix_socket(int *sock, const char *sockfile, const char *perm, uid_
unlink(sockfile);

/* Set up the UNIX domain socket. */
#if defined(DEBUG_FD_LEAKS) && DEBUG_FD_LEAKS == 1
uds_socket = __bbs_socket(PF_LOCAL, SOCK_STREAM, 0, file, line, func);
#else
UNUSED(file);
UNUSED(line);
UNUSED(func);
uds_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
#endif
if (uds_socket < 0) {
bbs_error("Unable to create UNIX domain socket: %s\n", strerror(errno));
return -1;
Expand Down Expand Up @@ -105,13 +112,20 @@ int bbs_make_unix_socket(int *sock, const char *sockfile, const char *perm, uid_
return 0;
}

int bbs_make_tcp_socket(int *sock, int port)
int __bbs_make_tcp_socket(int *sock, int port, const char *file, int line, const char *func)
{
struct sockaddr_in sinaddr; /* Internet socket */
const int enable = 1;
int res;

#if defined(DEBUG_FD_LEAKS) && DEBUG_FD_LEAKS == 1
*sock = __bbs_socket(AF_INET, SOCK_STREAM, 0, file, line, func);
#else
UNUSED(file);
UNUSED(line);
UNUSED(func);
*sock = socket(AF_INET, SOCK_STREAM, 0);
#endif
if (*sock < 0) {
bbs_error("Unable to create TCP socket: %s\n", strerror(errno));
return -1;
Expand Down Expand Up @@ -317,7 +331,7 @@ int bbs_resolve_hostname(const char *hostname, char *buf, size_t len)
return 0;
}

int bbs_tcp_connect(const char *hostname, int port)
int __bbs_tcp_connect(const char *hostname, int port, const char *file, int line, const char *func)
{
char ip[256];
int e;
Expand Down Expand Up @@ -353,7 +367,16 @@ int bbs_tcp_connect(const char *hostname, int port)
} else {
continue;
}

#if defined(DEBUG_FD_LEAKS) && DEBUG_FD_LEAKS == 1
sfd = __bbs_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol, file, line, func);
#else
UNUSED(file);
UNUSED(line);
UNUSED(func);
sfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
#endif

if (sfd == -1) {
bbs_error("socket: %s\n", strerror(errno));
continue;
Expand Down
10 changes: 9 additions & 1 deletion bbs/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,14 +352,22 @@ int bbs_str_anyprint(const char *restrict s)
return 0;
}

void str_tolower(char *restrict s)
void bbs_str_tolower(char *restrict s)
{
while (*s) {
*s = (char) tolower(*s);
s++;
}
}

void bbs_str_toupper(char *restrict s)
{
while (*s) {
*s = (char) toupper(*s);
s++;
}
}

int skipn(char **str, char c, int n)
{
int count = 0;
Expand Down
4 changes: 3 additions & 1 deletion include/alertpipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ ssize_t bbs_alertpipe_write(int alert_pipe[2]);
int bbs_alertpipe_read(int alert_pipe[2]);

/*! \brief Initialize an alertpipe */
int bbs_alertpipe_create(int alert_pipe[2]);
#define bbs_alertpipe_create(alert_pipe) __bbs_alertpipe_create(alert_pipe, __FILE__, __LINE__, __func__)

int __bbs_alertpipe_create(int alert_pipe[2], const char *file, int line, const char *func);

/*! \brief Close an alertpipe */
int bbs_alertpipe_close(int alert_pipe[2]);
Expand Down
46 changes: 23 additions & 23 deletions include/bbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,29 +110,29 @@
*/

#if defined(DEBUG_FD_LEAKS) && DEBUG_FD_LEAKS == 1
#define open(a,...) __fdleak_open(__FILE__,__LINE__,__func__, a, __VA_ARGS__)
#define pipe(a) __fdleak_pipe(a, __FILE__,__LINE__,__func__)
#define socketpair(a,b,c,d) __fdleak_socketpair(a, b, c, d, __FILE__,__LINE__,__func__)
#define socket(a,b,c) __fdleak_socket(a, b, c, __FILE__,__LINE__,__func__)
#define accept(a,b,c) __fdleak_accept(a, b, c, __FILE__,__LINE__,__func__)
#define close(a) __fdleak_close(a, __FILE__,__LINE__,__func__)
#define fopen(a,b) __fdleak_fopen(a, b, __FILE__,__LINE__,__func__)
#define fclose(a) __fdleak_fclose(a)
#define dup2(a,b) __fdleak_dup2(a, b, __FILE__,__LINE__,__func__)
#define dup(a) __fdleak_dup(a, __FILE__,__LINE__,__func__)
#define eventfd(a,b) __fdleak_eventfd(a,b, __FILE__,__LINE__,__func__)

int __fdleak_open(const char *file, int line, const char *func, const char *path, int flags, ...);
int __fdleak_pipe(int *fds, const char *file, int line, const char *func);
int __fdleak_socketpair(int domain, int type, int protocol, int sv[2], const char *file, int line, const char *func);
int __fdleak_socket(int domain, int type, int protocol, const char *file, int line, const char *func);
int __fdleak_accept(int socket, struct sockaddr *address, socklen_t *address_len, const char *file, int line, const char *func);
int __fdleak_eventfd(unsigned int initval, int flags, const char *file, int line, const char *func);
int __fdleak_close(int fd, const char *file, int line, const char *func);
FILE *__fdleak_fopen(const char *path, const char *mode, const char *file, int line, const char *func);
int __fdleak_fclose(FILE *ptr);
int __fdleak_dup2(int oldfd, int newfd, const char *file, int line, const char *func);
int __fdleak_dup(int oldfd, const char *file, int line, const char *func);
#define open(a,...) __bbs_open(__FILE__,__LINE__,__func__, a, __VA_ARGS__)
#define pipe(a) __bbs_pipe(a, __FILE__,__LINE__,__func__)
#define socketpair(a,b,c,d) __bbs_socketpair(a, b, c, d, __FILE__,__LINE__,__func__)
#define socket(a,b,c) __bbs_socket(a, b, c, __FILE__,__LINE__,__func__)
#define accept(a,b,c) __bbs_accept(a, b, c, __FILE__,__LINE__,__func__)
#define close(a) __bbs_close(a, __FILE__,__LINE__,__func__)
#define fopen(a,b) __bbs_fopen(a, b, __FILE__,__LINE__,__func__)
#define fclose(a) __bbs_fclose(a)
#define dup2(a,b) __bbs_dup2(a, b, __FILE__,__LINE__,__func__)
#define dup(a) __bbs_dup(a, __FILE__,__LINE__,__func__)
#define eventfd(a,b) __bbs_eventfd(a, b, __FILE__,__LINE__,__func__)

int __bbs_open(const char *file, int line, const char *func, const char *path, int flags, ...);
int __bbs_pipe(int *fds, const char *file, int line, const char *func);
int __bbs_socketpair(int domain, int type, int protocol, int sv[2], const char *file, int line, const char *func);
int __bbs_socket(int domain, int type, int protocol, const char *file, int line, const char *func);
int __bbs_accept(int socket, struct sockaddr *address, socklen_t *address_len, const char *file, int line, const char *func);
int __bbs_eventfd(unsigned int initval, int flags, const char *file, int line, const char *func);
int __bbs_close(int fd, const char *file, int line, const char *func);
FILE *__bbs_fopen(const char *path, const char *mode, const char *file, int line, const char *func);
int __bbs_fclose(FILE *ptr);
int __bbs_dup2(int oldfd, int newfd, const char *file, int line, const char *func);
int __bbs_dup(int oldfd, const char *file, int line, const char *func);

void bbs_fd_shutdown(void);
int bbs_fd_init(void);
Expand Down
50 changes: 50 additions & 0 deletions include/linkedlists.h
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,56 @@ struct { \
__elm_outer; \
})

/*!
* \brief Removes a specific entry from a list, by an attribute string comparison match.
* \param head This is a pointer to the list head structure
* \param attribute The attribute by which to look for a match via string comparison
* \param value The value that the attribute must have to match
* \param field This is the name of the field (declared using RWLIST_ENTRY())
* used to link entries of this list together.
* \retval Removed element
* \retval NULL if no matching element was found.
* \warning The removed entry is \b not freed.
*/
#define RWLIST_REMOVE_BY_STRING_FIELD(head, attribute, value, field) \
({ \
typeof((head)->first) __elm = NULL; \
if ((head)->first && !strcmp((head)->first->attribute, value)) { \
__elm = (head)->first; \
(head)->first = __elm->field.next; \
__elm->field.next = NULL; \
if ((head)->last == __elm) { \
(head)->last = NULL; \
} \
} else { \
typeof((head)->first) __prev = (head)->first; \
while (__prev && __prev->field.next && strcmp(__prev->field.next->attribute, value)) { \
__prev = __prev->field.next; \
} \
if (__prev) { \
__elm = (__prev)->field.next; \
if (__elm) { \
__prev->field.next = __elm->field.next; \
__elm->field.next = NULL; \
} \
if ((head)->last == __elm) { \
(head)->last = __prev; \
} \
} else { \
__elm = NULL; \
} \
} \
__elm; \
})

#define RWLIST_WRLOCK_REMOVE_BY_STRING_FIELD(head, attribute, value, field) ({ \
typeof((head)->first) __elm_outer = NULL; \
RWLIST_WRLOCK(head); \
__elm_outer = RWLIST_REMOVE_BY_STRING_FIELD(head, attribute, value, field); \
RWLIST_UNLOCK(head); \
__elm_outer; \
})

/*!
* \brief Removes all the entries from a list and invokes a destructor on each entry
* \param head This is a pointer to the list head structure
Expand Down
12 changes: 9 additions & 3 deletions include/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,19 @@
* \param gid Group ID. -1 to not change.
* \retval 0 on success, -1 on failure
*/
int bbs_make_unix_socket(int *sock, const char *sockfile, const char *perm, uid_t uid, gid_t gid);
#define bbs_make_unix_socket(sock, sockfile, perm, uid, gid) __bbs_make_unix_socket(sock, sockfile, perm, uid, gid, __FILE__, __LINE__, __func__)

int __bbs_make_unix_socket(int *sock, const char *sockfile, const char *perm, uid_t uid, gid_t gid, const char *file, int line, const char *func);

/*!
* \brief Create a TCP socket
* \param sock Pointer to socket
* \param port Port number on which to create the socket
* \retval 0 on success, -1 on failure
*/
int bbs_make_tcp_socket(int *sock, int port);
#define bbs_make_tcp_socket(sock, port) __bbs_make_tcp_socket(sock, port, __FILE__, __LINE__, __func__)

int __bbs_make_tcp_socket(int *sock, int port, const char *file, int line, const char *func);

/*! \brief Put a socket in nonblocking mode */
int bbs_unblock_fd(int fd);
Expand Down Expand Up @@ -63,7 +67,9 @@ int bbs_resolve_hostname(const char *hostname, char *buf, size_t len);
* \retval -1 on failure, socket file descriptor otherwise
* \note This does not perform TLS negotiation, use ssl_client_new immediately or later in the session for encryption.
*/
int bbs_tcp_connect(const char *hostname, int port);
#define bbs_tcp_connect(hostname, port) __bbs_tcp_connect(hostname, port, __FILE__, __LINE__, __func__)

int __bbs_tcp_connect(const char *hostname, int port, const char *file, int line, const char *func);

/*!
* \brief Wrapper around accept(), with poll timeout
Expand Down
5 changes: 4 additions & 1 deletion include/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,10 @@ int bbs_str_isprint(const char *restrict s) __attribute__ ((pure));
int bbs_str_anyprint(const char *restrict s) __attribute__ ((pure));

/*! \brief Convert a string to all lowercase */
void str_tolower(char *restrict s);
void bbs_str_tolower(char *restrict s);

/*! \brief Convert a string to all uppercase */
void bbs_str_toupper(char *restrict s);

/*!
* \brief Skip a number of occurences of a character in a string
Expand Down
Loading

0 comments on commit f3ad32d

Please sign in to comment.