X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=net.c;h=fa7cd4b80a7d96b26e35add01ad97d9a123f138d;hp=9698e427868e212646f682d9b8dc2d7e8f6235ae;hb=1709cc8f8a54429441f8f83c38146e667133c727;hpb=00e95557839f3fef5fa06702f3864e8376d2a29b diff --git a/net.c b/net.c index 9698e427..fa7cd4b8 100644 --- a/net.c +++ b/net.c @@ -6,11 +6,7 @@ /** \file net.c Networking-related helper functions. */ -/* - * Since glibc 2.8, the _GNU_SOURCE feature test macro must be defined in order - * to obtain the definition of the ucred structure. - */ -#define _GNU_SOURCE +#include "para.h" #include #include @@ -32,7 +28,6 @@ #include -#include "para.h" #include "error.h" #include "net.h" #include "string.h" @@ -180,8 +175,7 @@ char *parse_url(const char *url, } if (*o == ':') - if (para_atoi32(++o, port) < 0 || - *port < 0 || *port > 0xffff) + if (para_atoi32(++o, port) < 0 || *port < 0 || *port > 0xffff) goto failed; if (host_string_ok(host)) return host; @@ -192,6 +186,7 @@ failed: /** * Stringify port number, resolve into service name where defined. + * * \param port 2-byte port number, in host-byte-order. * \param transport Transport protocol name (e.g. "udp", "tcp"), or NULL. * \return Pointer to static result buffer. @@ -381,7 +376,7 @@ int lookup_address(unsigned l4type, bool passive, const char *host, struct addrinfo *addr = NULL, hints; *result = NULL; - sprintf(port, "%u", port_number & 0xffff); + sprintf(port, "%d", port_number & 0xffff); /* Set up address hint structure */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; @@ -834,13 +829,14 @@ int dccp_available_ccids(uint8_t **ccid_array) * \return Positive on success, \p -E_NAME_TOO_LONG if \a name is longer * than \p UNIX_PATH_MAX. */ -static int init_unix_addr(struct sockaddr_un *u, const char *name) +static int init_unix_addr(struct sockaddr_un *u, const char *name, + bool abstract) { - if (strlen(name) >= UNIX_PATH_MAX) + if (strlen(name) + abstract >= UNIX_PATH_MAX) return -E_NAME_TOO_LONG; memset(u->sun_path, 0, UNIX_PATH_MAX); u->sun_family = PF_UNIX; - strcpy(u->sun_path, name); + strcpy(u->sun_path + abstract, name); return 1; } @@ -855,6 +851,10 @@ static int init_unix_addr(struct sockaddr_un *u, const char *name) * nonblocking mode and listen(2) is called to prepare the socket for * accepting incoming connection requests. * + * If mode is zero, an abstract socket (a non-portable Linux extension) is + * created. In this case the socket name has no connection with filesystem + * pathnames. + * * \return The file descriptor on success, negative error code on failure. * * \sa socket(2), \sa bind(2), \sa chmod(2), listen(2), unix(7). @@ -863,8 +863,9 @@ int create_local_socket(const char *name, mode_t mode) { struct sockaddr_un unix_addr; int fd, ret; + bool abstract = mode == 0; - ret = init_unix_addr(&unix_addr, name); + ret = init_unix_addr(&unix_addr, name, abstract); if (ret < 0) return ret; ret = socket(PF_UNIX, SOCK_STREAM, 0); @@ -874,14 +875,16 @@ int create_local_socket(const char *name, mode_t mode) ret = mark_fd_nonblocking(fd); if (ret < 0) goto err; - ret = bind(fd, (struct sockaddr *)&unix_addr, UNIX_PATH_MAX); + ret = bind(fd, (struct sockaddr *)&unix_addr, sizeof(unix_addr)); if (ret < 0) { ret = -ERRNO_TO_PARA_ERROR(errno); goto err; } - ret = -E_CHMOD; - if (chmod(name, mode) < 0) - goto err; + if (!abstract) { + ret = -E_CHMOD; + if (chmod(name, mode) < 0) + goto err; + } if (listen(fd , 5) < 0) { ret = -ERRNO_TO_PARA_ERROR(errno); goto err; @@ -911,17 +914,22 @@ int connect_local_socket(const char *name) int fd, ret; PARA_DEBUG_LOG("connecting to %s\n", name); - ret = init_unix_addr(&unix_addr, name); - if (ret < 0) - return ret; fd = socket(PF_UNIX, SOCK_STREAM, 0); if (fd < 0) return -ERRNO_TO_PARA_ERROR(errno); - if (connect(fd, (struct sockaddr *)&unix_addr, sizeof(unix_addr)) == -1) { - ret = -ERRNO_TO_PARA_ERROR(errno); + /* first try (linux-only) abstract socket */ + ret = init_unix_addr(&unix_addr, name, true); + if (ret < 0) goto err; - } - return fd; + if (connect(fd, (struct sockaddr *)&unix_addr, sizeof(unix_addr)) != -1) + return fd; + /* next try pathname socket */ + ret = init_unix_addr(&unix_addr, name, false); + if (ret < 0) + goto err; + if (connect(fd, (struct sockaddr *)&unix_addr, sizeof(unix_addr)) != -1) + return fd; + ret = -ERRNO_TO_PARA_ERROR(errno); err: close(fd); return ret; @@ -1005,7 +1013,7 @@ static void dispose_fds(int *fds, unsigned num) */ int recv_cred_buffer(int fd, char *buf, size_t size) { - char control[255]; + char control[255] __a_aligned(8); struct msghdr msg; struct cmsghdr *cmsg; struct iovec iov;