Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:16.0:Staging:adi:10
pidentd
pidentd-ipv6.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pidentd-ipv6.patch of Package pidentd
--- src/conf.c.orig +++ src/conf.c @@ -103,7 +103,7 @@ conf_parse(const char *path, else if (strcasecmp(cp, "server:port") == 0) { - if (str2port(arg, &listen_port) < 0) + if (str2str(arg, &listen_port) < 0) syslog(LOG_ERR, "%s: %d: invalid port: %s", path, line, arg); } --- src/k_linux.c.orig +++ src/k_linux.c @@ -81,6 +81,7 @@ static int netlink_lookup(struct kainfo *kip, struct kernel *kp) { int status; + int i; struct { struct nlmsghdr nlh; union { @@ -95,12 +96,34 @@ netlink_lookup(struct kainfo *kip, struc buf.nlh.nlmsg_type = TCPDIAG_GETSOCK; buf.nlh.nlmsg_flags = NLM_F_REQUEST; buf.nlh.nlmsg_seq = ++kip->seq; - buf.u.req.idiag_family = AF_INET; + buf.u.req.idiag_family = kp->remote.sg_addr._sg_sa.sa_family; - buf.u.req.id.idiag_dport = kp->remote.sin_port; - buf.u.req.id.idiag_sport = kp->local.sin_port; - buf.u.req.id.idiag_dst[0] = kp->remote.sin_addr.s_addr; - buf.u.req.id.idiag_src[0] = kp->local.sin_addr.s_addr; + switch (buf.u.req.idiag_family) { + + case AF_INET: + buf.u.req.id.idiag_dport = kp->remote.sg_addr._sg_sin.sin_port; + buf.u.req.id.idiag_sport = kp->local.sg_addr._sg_sin.sin_port; + buf.u.req.id.idiag_dst[0] = kp->remote.sg_addr._sg_sin.sin_addr.s_addr; + buf.u.req.id.idiag_src[0] = kp->local.sg_addr._sg_sin.sin_addr.s_addr; + break; + + case AF_INET6: + buf.u.req.id.idiag_dport = kp->remote.sg_addr._sg_sin6.sin6_port; + buf.u.req.id.idiag_sport = kp->local.sg_addr._sg_sin6.sin6_port; + + for (i = 0; i < 4; i++) { + buf.u.req.id.idiag_dst[i] = + kp->remote.sg_addr._sg_sin6.sin6_addr.__in6_u.__u6_addr32[i]; + buf.u.req.id.idiag_src[i] = + kp->local.sg_addr._sg_sin6.sin6_addr.__in6_u.__u6_addr32[i]; + } + break; + + default: + syslog(LOG_ERR, "netlink_lookup: unknown address family: %d", + buf.u.req.idiag_family); + return 3; + } buf.u.req.id.idiag_cookie[0] = INET_DIAG_NOCOOKIE; buf.u.req.id.idiag_cookie[1] = INET_DIAG_NOCOOKIE; @@ -181,10 +204,10 @@ ka_lookup(void *vp, struct kernel *kp) if (kip->nlfd >= 0) return netlink_lookup(kip, kp); - r_rport = ntohs(kp->remote.sin_port); - r_lport = ntohs(kp->local.sin_port); - r_raddr = kp->remote.sin_addr.s_addr; - r_laddr = kp->local.sin_addr.s_addr; + r_rport = ntohs(kp->remote.sg_addr._sg_sin.sin_port); + r_lport = ntohs(kp->local.sg_addr._sg_sin.sin_port); + r_raddr = kp->remote.sg_addr._sg_sin.sin_addr.s_addr; + r_laddr = kp->local.sg_addr._sg_sin.sin_addr.s_addr; fp = kip->proc_net_tcp; --- src/main.c.orig +++ src/main.c @@ -162,8 +162,9 @@ main(int argc, char *argv[]) if (debug) fprintf(stderr, "socktype = %d\n", socket_type); - if (socket_type == SOCKTYPE_LISTEN || socket_type == SOCKTYPE_CONNECTED) - listen_sock = STDIN_FILENO; + if (socket_type == SOCKTYPE_LISTEN || socket_type == SOCKTYPE_CONNECTED) { + server_set_socket(STDIN_FILENO); + } conf_parse(PATH_CFGFILE, 1); @@ -198,23 +199,23 @@ main(int argc, char *argv[]) break; case 'w': - listen_sock = STDIN_FILENO; + server_set_socket(STDIN_FILENO); socket_type = SOCKTYPE_LISTEN; break; case 'i': - listen_sock = STDIN_FILENO; + server_set_socket(STDIN_FILENO); socket_type = SOCKTYPE_CONNECTED; break; case 'I': - listen_sock = -1; + server_set_socket(-1); socket_type = SOCKTYPE_NOTSOCKET; init_mode = 1; break; case 'b': - listen_sock = -1; + server_set_socket(-1); socket_type = SOCKTYPE_NOTSOCKET; break; @@ -223,7 +224,7 @@ main(int argc, char *argv[]) break; case 'p': - if (str2port(optarg, &listen_port) < 0) + if (str2str(optarg, &listen_port) < 0) { syslog(LOG_ERR, "invalid argument to '-p': %s", optarg); if (socket_type == -1 || socket_type == SOCKTYPE_NOTSOCKET) @@ -352,7 +353,7 @@ main(int argc, char *argv[]) if (!debug && getppid() != INIT_PID && !init_mode && socket_type != SOCKTYPE_CONNECTED && - listen_sock < 0) + listen_count == 0) { become_daemon(); } @@ -380,7 +381,7 @@ main(int argc, char *argv[]) if (!debug && pidfile_path != NULL) pidfile_create(pidfile_path); - if (listen_sock < 0) + if (listen_count == 0) { request_timeout = 0; } @@ -442,7 +443,7 @@ main(int argc, char *argv[]) server_run(); } else - return request_run(listen_sock, 1); + return request_run(listen_socks[0], 1); Exit: syslog(LOG_DEBUG, "terminating"); --- src/server.c.orig +++ src/server.c @@ -28,9 +28,10 @@ -int listen_sock = -1; -int listen_port = IPPORT_IDENT; -int listen_addr = INADDR_ANY; +int *listen_socks; +int listen_count = 0; +char *listen_port = "ident"; +char *listen_addr = NULL; int listen_backlog = 256; @@ -60,14 +61,30 @@ unlimit_nofile(void) #endif } +void +server_set_socket(int fd) +{ + if (listen_socks != NULL) { + free(listen_socks); + listen_socks = NULL; + } + if (fd < 0) { + listen_count = 0; + } else { + listen_socks = malloc(sizeof(*listen_socks)); + listen_socks[0] = fd; + listen_count = 1; + } +} int server_init(void) { static int one = 1; int nofile; - struct sockaddr_in sin; - + struct addrinfo hints; + struct addrinfo *result, *rp; + int s; /* ** Increase the number of available file descriptors @@ -77,91 +94,120 @@ server_init(void) if (nofile < 0) return -1; + if (listen_count > 0) { + return 0; + } - if (listen_sock < 0) - { - listen_sock = socket(AF_INET, SOCK_STREAM, 0); - if (listen_sock < 0) - { - syslog(LOG_ERR, "socket(AF_INET, SOCK_STREAM) failed: %m"); - return -1; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + + s = getaddrinfo(listen_addr, listen_port, &hints, &result); + if (s != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); + exit(EXIT_FAILURE); + } + + for (rp = result; rp != NULL; rp = rp->ai_next) { + int sock; + + sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + + if (sock < 0) { + syslog(LOG_ERR, "socket() failed: %m"); + continue; } - (void) setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, - (void *) &one, sizeof(one)); + if (rp->ai_family == AF_INET6) { + if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, + (void *) &one, sizeof(one)) < 0) { + syslog(LOG_ERR, "setsockopt(IPV6_V6ONLY,) failed: %m"); + close(sock); + continue; + } + } + + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + (void *) &one, sizeof(one)) < 0) { + syslog(LOG_ERR, "setsockopt(SO_REUSEADDR) failed: %m"); + close(sock); + continue; + } - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(listen_addr); - sin.sin_port = htons(listen_port); - - if (bind(listen_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) - { - syslog(LOG_ERR, "bind(port=%d) failed: %m", + if (bind(sock, rp->ai_addr, rp->ai_addrlen) < 0) { + syslog(LOG_ERR, "bind(port=%s) failed: %m", listen_port); - return -1; + close(sock); + continue; } - } - /* We do this outside of the 'if' statement to support - some broken 'inetd' daemons... */ - if (listen(listen_sock, listen_backlog) < 0) - { - syslog(LOG_ERR, "listen(backlog=%d) failed: %m", listen_backlog); - return -1; + if (listen(sock, listen_backlog) < 0) { + syslog(LOG_ERR, "listen(backlog=%d) failed: %m", listen_backlog); + close(sock); + continue; + } + + if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) { + syslog(LOG_ERR, "fcntl() failed: %m"); + close(sock); + continue; + } + + listen_socks = realloc(listen_socks, + sizeof(listen_socks) * listen_count); + listen_socks[listen_count] = sock; + listen_count++; } - return 0; + return listen_count ? 0 : 1; } int server_run(void) { - struct pollfd ufds[1]; - int fd; + struct pollfd ufds[listen_count]; + int i, fd; int timeout = request_timeout <= 0 ? -1 : request_timeout * 1000; int retval; - if (fcntl(listen_sock, F_SETFL, O_NONBLOCK) == -1) - { - syslog(LOG_ERR, "fcntl() failed: %m"); - return -1; + for (i = 0; i < listen_count; i++) { + ufds[i].fd = listen_socks[i]; + ufds[i].events = POLLIN; } - - ufds[0].fd = listen_sock; - ufds[0].events = POLLIN; - while (1) - { - if ((retval = s_poll(ufds, 1, timeout)) == -1) - { + while (1) { + if ((retval = s_poll(ufds, listen_count, timeout)) == -1) { syslog(LOG_ERR, "poll() failed: %m"); return -1; } else if (retval == 0) break; - fd = s_accept(listen_sock, NULL, NULL); - if (fd < 0) - { - syslog(LOG_ERR, "accept() failed: %m"); - - switch (errno) - { - case EBADF: - case EMFILE: - case ENODEV: - case ENOMEM: - case ENOTSOCK: - case EOPNOTSUPP: - case EWOULDBLOCK: - return -1; + for (i = 0; i < listen_count; i++) { + + if (ufds[i].revents & POLLIN) { + + fd = s_accept(listen_socks[i], NULL, NULL); + if (fd < 0) { + syslog(LOG_ERR, "accept() failed: %m"); + + switch (errno) { + case EBADF: + case EMFILE: + case ENODEV: + case ENOMEM: + case ENOTSOCK: + case EOPNOTSUPP: + case EWOULDBLOCK: + return -1; + } + } else { + request_run(fd, 0); + } } } - - request_run(fd, 0); } - if (debug) fprintf(stderr, "accept() timed out\n"); exit(0); --- src/server.h.orig +++ src/server.h @@ -15,13 +15,15 @@ #ifndef PIDENTD_SERVER_H #define PIDENTD_SERVER_H -extern int listen_sock; -extern int listen_port; -extern int listen_addr; +extern int *listen_socks; +extern int listen_count; +extern char *listen_port; +extern char *listen_addr; extern int listen_backlog; extern int server_init(void); extern int server_run(void); +extern void server_set_socket(int); #endif --- src/sockaddr.h.orig +++ src/sockaddr.h @@ -18,6 +18,7 @@ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> +#include <netdb.h> #ifdef HAVE_IPV6
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor