summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/activate/activate.c23
-rw-r--r--src/basic/socket-label.c6
-rw-r--r--src/basic/socket-util.c4
-rw-r--r--src/basic/socket-util.h4
-rw-r--r--src/core/service.c2
-rw-r--r--src/journal-remote/journal-remote.c8
-rw-r--r--src/socket-proxy/socket-proxyd.c2
7 files changed, 34 insertions, 15 deletions
diff --git a/src/activate/activate.c b/src/activate/activate.c
index b7e6255f49..95083441ab 100644
--- a/src/activate/activate.c
+++ b/src/activate/activate.c
@@ -39,6 +39,7 @@
static char** arg_listen = NULL;
static bool arg_accept = false;
+static bool arg_datagram = false;
static char** arg_args = NULL;
static char** arg_setenv = NULL;
static const char *arg_fdname = NULL;
@@ -98,7 +99,11 @@ static int open_sockets(int *epoll_fd, bool accept) {
STRV_FOREACH(address, arg_listen) {
- fd = make_socket_fd(LOG_DEBUG, *address, SOCK_STREAM | (arg_accept*SOCK_CLOEXEC));
+ if (arg_datagram)
+ fd = make_socket_fd(LOG_DEBUG, *address, SOCK_DGRAM, SOCK_CLOEXEC);
+ else
+ fd = make_socket_fd(LOG_DEBUG, *address, SOCK_STREAM, (arg_accept*SOCK_CLOEXEC));
+
if (fd < 0) {
log_open();
return log_error_errno(fd, "Failed to open '%s': %m", *address);
@@ -272,7 +277,7 @@ static int do_accept(const char* name, char **argv, char **envp, int fd) {
}
getsockname_pretty(fd2, &local);
- getpeername_pretty(fd2, &peer);
+ getpeername_pretty(fd2, true, &peer);
log_info("Connection from %s to %s", strna(peer), strna(local));
return launch1(name, argv, envp, fd2);
@@ -304,6 +309,7 @@ static void help(void) {
printf("%s [OPTIONS...]\n\n"
"Listen on sockets and launch child on connection.\n\n"
"Options:\n"
+ " -d --datagram Datagram sockets\n"
" -l --listen=ADDR Listen for raw connections at ADDR\n"
" -a --accept Spawn separate child for each connection\n"
" -h --help Show this help and exit\n"
@@ -323,6 +329,7 @@ static int parse_argv(int argc, char *argv[]) {
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
+ { "datagram", no_argument, NULL, 'd' },
{ "listen", required_argument, NULL, 'l' },
{ "accept", no_argument, NULL, 'a' },
{ "setenv", required_argument, NULL, 'E' },
@@ -336,7 +343,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "+hl:aE:", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "+hl:aEd", options, NULL)) >= 0)
switch(c) {
case 'h':
help();
@@ -352,6 +359,10 @@ static int parse_argv(int argc, char *argv[]) {
break;
+ case 'd':
+ arg_datagram = true;
+ break;
+
case 'a':
arg_accept = true;
break;
@@ -385,6 +396,12 @@ static int parse_argv(int argc, char *argv[]) {
return -EINVAL;
}
+ if (arg_datagram && arg_accept) {
+ log_error("Datagram sockets do not accept connections. "
+ "The --datagram and --accept options may not be combined.");
+ return -EINVAL;
+ }
+
arg_args = argv + optind;
return 1 /* work to do */;
diff --git a/src/basic/socket-label.c b/src/basic/socket-label.c
index e169439e04..bd206586ce 100644
--- a/src/basic/socket-label.c
+++ b/src/basic/socket-label.c
@@ -147,7 +147,7 @@ int socket_address_listen(
return r;
}
-int make_socket_fd(int log_level, const char* address, int flags) {
+int make_socket_fd(int log_level, const char* address, int type, int flags) {
SocketAddress a;
int fd, r;
@@ -155,7 +155,9 @@ int make_socket_fd(int log_level, const char* address, int flags) {
if (r < 0)
return log_error_errno(r, "Failed to parse socket address \"%s\": %m", address);
- fd = socket_address_listen(&a, flags, SOMAXCONN, SOCKET_ADDRESS_DEFAULT,
+ a.type = type;
+
+ fd = socket_address_listen(&a, type | flags, SOMAXCONN, SOCKET_ADDRESS_DEFAULT,
NULL, false, false, false, 0755, 0644, NULL);
if (fd < 0 || log_get_max_level() >= log_level) {
_cleanup_free_ char *p = NULL;
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index be144e157d..f2bb3bab86 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -601,7 +601,7 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_
return 0;
}
-int getpeername_pretty(int fd, char **ret) {
+int getpeername_pretty(int fd, bool include_port, char **ret) {
union sockaddr_union sa;
socklen_t salen = sizeof(sa);
int r;
@@ -631,7 +631,7 @@ int getpeername_pretty(int fd, char **ret) {
/* For remote sockets we translate IPv6 addresses back to IPv4
* if applicable, since that's nicer. */
- return sockaddr_pretty(&sa.sa, salen, true, true, ret);
+ return sockaddr_pretty(&sa.sa, salen, true, include_port, ret);
}
int getsockname_pretty(int fd, char **ret) {
diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h
index 6da1df68d8..2323ccf3ab 100644
--- a/src/basic/socket-util.h
+++ b/src/basic/socket-util.h
@@ -89,7 +89,7 @@ int socket_address_listen(
mode_t directory_mode,
mode_t socket_mode,
const char *label);
-int make_socket_fd(int log_level, const char* address, int flags);
+int make_socket_fd(int log_level, const char* address, int type, int flags);
bool socket_address_is(const SocketAddress *a, const char *s, int type);
bool socket_address_is_netlink(const SocketAddress *a, const char *s);
@@ -105,7 +105,7 @@ bool socket_ipv6_is_supported(void);
int sockaddr_port(const struct sockaddr *_sa) _pure_;
int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret);
-int getpeername_pretty(int fd, char **ret);
+int getpeername_pretty(int fd, bool include_port, char **ret);
int getsockname_pretty(int fd, char **ret);
int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret);
diff --git a/src/core/service.c b/src/core/service.c
index c5b689a35c..ae84cccbc8 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -3201,7 +3201,7 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock, bool selinux_context
if (s->state != SERVICE_DEAD)
return -EAGAIN;
- if (getpeername_pretty(fd, &peer) >= 0) {
+ if (getpeername_pretty(fd, true, &peer) >= 0) {
if (UNIT(s)->description) {
_cleanup_free_ char *a;
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
index 2126606661..e7003da9c1 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/journal-remote/journal-remote.c
@@ -447,7 +447,7 @@ static int add_raw_socket(RemoteServer *s, int fd) {
static int setup_raw_socket(RemoteServer *s, const char *address) {
int fd;
- fd = make_socket_fd(LOG_INFO, address, SOCK_STREAM | SOCK_CLOEXEC);
+ fd = make_socket_fd(LOG_INFO, address, SOCK_STREAM, SOCK_CLOEXEC);
if (fd < 0)
return fd;
@@ -621,7 +621,7 @@ static int request_handler(
if (r < 0)
return code;
} else {
- r = getnameinfo_pretty(fd, &hostname);
+ r = getpeername_pretty(fd, false, &hostname);
if (r < 0)
return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR,
"Cannot check remote hostname");
@@ -765,7 +765,7 @@ static int setup_microhttpd_socket(RemoteServer *s,
const char *trust) {
int fd;
- fd = make_socket_fd(LOG_DEBUG, address, SOCK_STREAM | SOCK_CLOEXEC);
+ fd = make_socket_fd(LOG_DEBUG, address, SOCK_STREAM, SOCK_CLOEXEC);
if (fd < 0)
return fd;
@@ -879,7 +879,7 @@ static int remoteserver_init(RemoteServer *s,
} else if (sd_is_socket(fd, AF_UNSPEC, 0, false)) {
char *hostname;
- r = getnameinfo_pretty(fd, &hostname);
+ r = getpeername_pretty(fd, false, &hostname);
if (r < 0)
return log_error_errno(r, "Failed to retrieve remote name: %m");
diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c
index ba82adadb4..600f772e19 100644
--- a/src/socket-proxy/socket-proxyd.c
+++ b/src/socket-proxy/socket-proxyd.c
@@ -505,7 +505,7 @@ static int accept_cb(sd_event_source *s, int fd, uint32_t revents, void *userdat
if (errno != -EAGAIN)
log_warning_errno(errno, "Failed to accept() socket: %m");
} else {
- getpeername_pretty(nfd, &peer);
+ getpeername_pretty(nfd, true, &peer);
log_debug("New connection from %s", strna(peer));
r = add_connection_socket(context, nfd);