diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2016-12-20 14:10:54 +0000 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2017-01-10 15:29:04 +0000 |
commit | 882ac6e769c5c8d1742e49028043ba2ce691b045 (patch) | |
tree | 16a5cdccb61998e723fab3b489d7aa1464933d20 | |
parent | 4e0399e69b369f3d3543285592e977063cdcc014 (diff) |
socket-util: introduce port argument in sockaddr_port()
sockaddr_port() either returns a >= 0 port number or a negative errno.
This works for AF_INET and AF_INET6 because port ranges are only 16-bit.
In AF_VSOCK ports are 32-bit so an int cannot represent all port number
and negative errnos. Separate the port and the return code.
-rw-r--r-- | src/basic/socket-util.c | 5 | ||||
-rw-r--r-- | src/basic/socket-util.h | 2 | ||||
-rw-r--r-- | src/core/service.c | 8 |
3 files changed, 8 insertions, 7 deletions
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 4ebf106109..16f9bbc940 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -480,7 +480,7 @@ bool socket_address_matches_fd(const SocketAddress *a, int fd) { return socket_address_equal(a, &b); } -int sockaddr_port(const struct sockaddr *_sa) { +int sockaddr_port(const struct sockaddr *_sa, unsigned *port) { union sockaddr_union *sa = (union sockaddr_union*) _sa; assert(sa); @@ -488,7 +488,8 @@ int sockaddr_port(const struct sockaddr *_sa) { if (!IN_SET(sa->sa.sa_family, AF_INET, AF_INET6)) return -EAFNOSUPPORT; - return be16toh(sa->sa.sa_family == AF_INET6 ? sa->in6.sin6_port : sa->in.sin_port); + *port = be16toh(sa->sa.sa_family == AF_INET6 ? sa->in6.sin6_port : sa->in.sin_port); + return 0; } int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) { diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h index 2ef572badb..482055fafa 100644 --- a/src/basic/socket-util.h +++ b/src/basic/socket-util.h @@ -100,7 +100,7 @@ const char* socket_address_get_path(const SocketAddress *a); bool socket_ipv6_is_supported(void); -int sockaddr_port(const struct sockaddr *_sa) _pure_; +int sockaddr_port(const struct sockaddr *_sa, unsigned *port) _pure_; int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret); int getpeername_pretty(int fd, bool include_port, char **ret); diff --git a/src/core/service.c b/src/core/service.c index 73a8104d17..dc7b685cd3 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1295,7 +1295,7 @@ static int service_spawn( if (r == 0 && IN_SET(sa.sa.sa_family, AF_INET, AF_INET6)) { _cleanup_free_ char *addr = NULL; char *t; - int port; + unsigned port; r = sockaddr_pretty(&sa.sa, salen, true, false, &addr); if (r < 0) @@ -1306,9 +1306,9 @@ static int service_spawn( return -ENOMEM; our_env[n_env++] = t; - port = sockaddr_port(&sa.sa); - if (port < 0) - return port; + r = sockaddr_port(&sa.sa, &port); + if (r < 0) + return r; if (asprintf(&t, "REMOTE_PORT=%u", port) < 0) return -ENOMEM; |