X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fbasic%2Fsocket-util.c;h=c1312c1d2940721cbc88b1cf9124ae9822d6111d;hb=9742b1e43855b1599bd52ff95af995d9a9d35eac;hp=4c1869353f31ff9d9e4f97ee92c2668105e5e27b;hpb=a683e1878913969ccf8b0defdec4d955e15ed75a;p=elogind.git diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 4c1869353..c1312c1d2 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -33,7 +33,7 @@ #include "alloc-util.h" #include "fd-util.h" #include "fileio.h" -#include "formats-util.h" +#include "format-util.h" #include "log.h" #include "macro.h" #include "missing.h" @@ -44,9 +44,16 @@ #include "string-util.h" #include "strv.h" #include "user-util.h" +//#include "utf8.h" #include "util.h" #if 0 /// UNNEEDED by elogind +#ifdef ENABLE_IDN +# define IDN_FLAGS (NI_IDN|NI_IDN_USE_STD3_ASCII_RULES) +#else +# define IDN_FLAGS 0 +#endif + int socket_address_parse(SocketAddress *a, const char *s) { char *e, *n; unsigned u; @@ -112,6 +119,30 @@ int socket_address_parse(SocketAddress *a, const char *s) { memcpy(a->sockaddr.un.sun_path+1, s+1, l); a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l; + } else if (startswith(s, "vsock:")) { + /* AF_VSOCK socket in vsock:cid:port notation */ + const char *cid_start = s + strlen("vsock:"); + + e = strchr(cid_start, ':'); + if (!e) + return -EINVAL; + + r = safe_atou(e+1, &u); + if (r < 0) + return r; + + n = strndupa(cid_start, e - cid_start); + if (!isempty(n)) { + r = safe_atou(n, &a->sockaddr.vm.svm_cid); + if (r < 0) + return r; + } else + a->sockaddr.vm.svm_cid = VMADDR_CID_ANY; + + a->sockaddr.vm.svm_family = AF_VSOCK; + a->sockaddr.vm.svm_port = u; + a->size = sizeof(struct sockaddr_vm); + } else { e = strchr(s, ':'); if (e) { @@ -288,6 +319,15 @@ int socket_address_verify(const SocketAddress *a) { return 0; + case AF_VSOCK: + if (a->size != sizeof(struct sockaddr_vm)) + return -EINVAL; + + if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM) + return -EINVAL; + + return 0; + default: return -EAFNOSUPPORT; } @@ -372,7 +412,7 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) { return false; if (a->sockaddr.un.sun_path[0]) { - if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path)) + if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, 0)) return false; } else { if (a->size != b->size) @@ -393,6 +433,15 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) { break; + case AF_VSOCK: + if (a->sockaddr.vm.svm_cid != b->sockaddr.vm.svm_cid) + return false; + + if (a->sockaddr.vm.svm_port != b->sockaddr.vm.svm_port) + return false; + + break; + default: /* Cannot compare, so we assume the addresses are different */ return false; @@ -438,7 +487,6 @@ const char* socket_address_get_path(const SocketAddress *a) { return a->sockaddr.un.sun_path; } -#endif // 0 bool socket_ipv6_is_supported(void) { if (access("/proc/net/if_inet6", F_OK) != 0) @@ -447,7 +495,6 @@ bool socket_ipv6_is_supported(void) { return true; } -#if 0 /// UNNEEDED by elogind bool socket_address_matches_fd(const SocketAddress *a, int fd) { SocketAddress b; socklen_t solen; @@ -481,15 +528,27 @@ 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); - if (!IN_SET(sa->sa.sa_family, AF_INET, AF_INET6)) - return -EAFNOSUPPORT; + switch (sa->sa.sa_family) { + case AF_INET: + *port = be16toh(sa->in.sin_port); + return 0; + + case AF_INET6: + *port = be16toh(sa->in6.sin6_port); + return 0; - return be16toh(sa->sa.sa_family == AF_INET6 ? sa->in6.sin6_port : sa->in.sin_port); + case AF_VSOCK: + *port = sa->vm.svm_port; + return 0; + + default: + return -EAFNOSUPPORT; + } } int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) { @@ -592,6 +651,18 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ break; + case AF_VSOCK: + if (include_port) + r = asprintf(&p, + "vsock:%u:%u", + sa->vm.svm_cid, + sa->vm.svm_port); + else + r = asprintf(&p, "vsock:%u", sa->vm.svm_cid); + if (r < 0) + return -ENOMEM; + break; + default: return -EOPNOTSUPP; } @@ -658,8 +729,7 @@ int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) assert(_ret); - r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0, - NI_IDN|NI_IDN_USE_STD3_ASCII_RULES); + r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0, IDN_FLAGS); if (r != 0) { int saved_errno = errno; @@ -749,6 +819,9 @@ bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b if (a->sa.sa_family == AF_INET6) return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0; + if (a->sa.sa_family == AF_VSOCK) + return a->vm.svm_cid == b->vm.svm_cid; + return false; } #endif // 0 @@ -797,7 +870,6 @@ static const char* const ip_tos_table[] = { }; DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff); -#endif // 0 bool ifname_valid(const char *p) { bool numeric = true; @@ -812,7 +884,7 @@ bool ifname_valid(const char *p) { if (strlen(p) >= IFNAMSIZ) return false; - if (STR_IN_SET(p, ".", "..")) + if (dot_or_dot_dot(p)) return false; while (*p) { @@ -835,6 +907,27 @@ bool ifname_valid(const char *p) { return true; } +bool address_label_valid(const char *p) { + + if (isempty(p)) + return false; + + if (strlen(p) >= IFNAMSIZ) + return false; + + while (*p) { + if ((uint8_t) *p >= 127U) + return false; + + if ((uint8_t) *p <= 31U) + return false; + p++; + } + + return true; +} +#endif // 0 + int getpeercred(int fd, struct ucred *ucred) { socklen_t n = sizeof(struct ucred); struct ucred u; @@ -1051,7 +1144,6 @@ int flush_accept(int fd) { close(cfd); } } -#endif // 0 struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length) { struct cmsghdr *cmsg; @@ -1067,7 +1159,6 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng return NULL; } -#if 0 /// UNNEEDED by elogind int socket_ioctl_fd(void) { int fd;