sock_events.c: also track child file descriptors
In some applications, such as OsmocomBB, a single UNIX socket can be used by multiple processes (i.e. a server and multiple clients). Previously this caused a segmentation fault. Let's modify both sock_ev_accept() and sock_ev_accept4() in order to handle such connections properly, by using both socket path and dissector from the parent.
This commit is contained in:
parent
0578d751b1
commit
04ac475170
|
@ -85,7 +85,8 @@ void sock_ev_accept(int fd, int ret, int err, struct sockaddr *addr,
|
||||||
{
|
{
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return;
|
return;
|
||||||
udtrace_add_fd(ret);
|
LOG("accept(fd=%d on parent fd=%d)\n", ret, fd);
|
||||||
|
udtrace_add_fd_child(fd, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sock_ev_accept4(int fd, int ret, int err, struct sockaddr *addr,
|
void sock_ev_accept4(int fd, int ret, int err, struct sockaddr *addr,
|
||||||
|
@ -93,7 +94,8 @@ void sock_ev_accept4(int fd, int ret, int err, struct sockaddr *addr,
|
||||||
{
|
{
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return;
|
return;
|
||||||
udtrace_add_fd(ret);
|
LOG("accept(fd=%d on parent fd=%d)\n", ret, fd);
|
||||||
|
udtrace_add_fd_child(fd, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sock_ev_send(int fd, int ret, int err, const void *buf, size_t bytes,
|
void sock_ev_send(int fd, int ret, int err, const void *buf, size_t bytes,
|
||||||
|
|
26
utils.c
26
utils.c
|
@ -85,6 +85,32 @@ void udtrace_add_fd(int fd)
|
||||||
ss->fd = fd;
|
ss->fd = fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* add a file descriptor from the list of to-be-traced ones */
|
||||||
|
void udtrace_add_fd_child(int pfd, int cfd)
|
||||||
|
{
|
||||||
|
struct sock_state *pss, *css;
|
||||||
|
|
||||||
|
/* Find the parent socket state first */
|
||||||
|
pss = udtrace_sstate_by_fd(pfd);
|
||||||
|
if (!pss) {
|
||||||
|
LOG("Couldn't find parent UNIX FD %d for %d\n", pfd, cfd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find an unused state in unix_fds */
|
||||||
|
css = udtrace_sstate_by_fd(-1);
|
||||||
|
if (!css) {
|
||||||
|
LOG("Couldn't add UNIX FD %d (no space in unix_fds)\n", cfd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG("Adding FD %d as a child of %d\n", cfd, pfd);
|
||||||
|
|
||||||
|
css->dissector = pss->dissector;
|
||||||
|
css->path = strdup(pss->path);
|
||||||
|
css->fd = cfd;
|
||||||
|
}
|
||||||
|
|
||||||
/* delete a file descriptor from the list of to-be-traced ones */
|
/* delete a file descriptor from the list of to-be-traced ones */
|
||||||
void udtrace_del_fd(int fd)
|
void udtrace_del_fd(int fd)
|
||||||
{
|
{
|
||||||
|
|
3
utils.h
3
utils.h
|
@ -21,6 +21,9 @@ struct sock_state *udtrace_sstate_by_fd(int fd);
|
||||||
/* add a file descriptor from the list of to-be-traced ones */
|
/* add a file descriptor from the list of to-be-traced ones */
|
||||||
void udtrace_add_fd(int fd);
|
void udtrace_add_fd(int fd);
|
||||||
|
|
||||||
|
/* add a file descriptor from the list of to-be-traced ones */
|
||||||
|
void udtrace_add_fd_child(int pfd, int cfd);
|
||||||
|
|
||||||
/* delete a file descriptor from the list of to-be-traced ones */
|
/* delete a file descriptor from the list of to-be-traced ones */
|
||||||
void udtrace_del_fd(int fd);
|
void udtrace_del_fd(int fd);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue