X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fsocket-util.c;h=e400bb543abc1cdbf34919aa84e9d111083c0849;hb=6d65eee8b1f4d96b9c925d3b31758268345a4636;hp=e5b86e42773a4105c9cac09a1b5b99523ff5124c;hpb=e3fdfed11b8c56aa6a8deffe11a552fed7e7adbc;p=openvswitch diff --git a/lib/socket-util.c b/lib/socket-util.c index e5b86e42..e400bb54 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -73,25 +73,16 @@ get_max_fds(void) return max_fds; } -/* Translates 'host_name', which may be a DNS name or an IP address, into a - * numeric IP address in '*addr'. Returns 0 if successful, otherwise a - * positive errno value. */ +/* Translates 'host_name', which must be a string representation of an IP + * address, into a numeric IP address in '*addr'. Returns 0 if successful, + * otherwise a positive errno value. */ int lookup_ip(const char *host_name, struct in_addr *addr) { if (!inet_aton(host_name, addr)) { - struct hostent *he = gethostbyname(host_name); - if (he == NULL) { - struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); - VLOG_ERR_RL(&rl, "gethostbyname(%s): %s", host_name, - (h_errno == HOST_NOT_FOUND ? "host not found" - : h_errno == TRY_AGAIN ? "try again" - : h_errno == NO_RECOVERY ? "non-recoverable error" - : h_errno == NO_ADDRESS ? "no address" - : "unknown error")); - return ENOENT; - } - addr->s_addr = *(uint32_t *) he->h_addr; + struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); + VLOG_ERR_RL(&rl, "\"%s\" is not a valid IP address", host_name); + return ENOENT; } return 0; } @@ -301,8 +292,9 @@ guess_netmask(uint32_t ip) } /* Opens a non-blocking TCP socket and connects to 'target', which should be a - * string in the format "[:]", where is required and - * is optional, with 'default_port' assumed if is omitted. + * string in the format "[:]". is required. If + * 'default_port' is nonzero then is optional and defaults to + * 'default_port'. * * On success, returns 0 (indicating connection complete) or EAGAIN (indicating * connection in progress), in which case the new file descriptor is stored @@ -344,6 +336,10 @@ tcp_open_active(const char *target_, uint16_t default_port, } if (port_string && atoi(port_string)) { sin.sin_port = htons(atoi(port_string)); + } else if (!default_port) { + VLOG_ERR("%s: port number must be specified", target_); + error = EAFNOSUPPORT; + goto exit; } /* Create non-blocking socket. */ @@ -385,10 +381,10 @@ exit: } /* Opens a non-blocking TCP socket, binds to 'target', and listens for incoming - * connections. 'target' should be a string in the format "[][:]", - * where both and are optional. If is omitted, it defaults - * to 'default_port'; if is omitted it defaults to the wildcard IP - * address. + * connections. 'target' should be a string in the format "[][:]". + * may be omitted if 'default_port' is nonzero, in which case it + * defaults to 'default_port'. If is omitted it defaults to the wildcard + * IP address. * * The socket will have SO_REUSEADDR turned on. * @@ -415,6 +411,10 @@ tcp_open_passive(const char *target_, uint16_t default_port) port_string = strsep(&string_ptr, ":"); if (port_string && atoi(port_string)) { sin.sin_port = htons(atoi(port_string)); + } else if (!default_port) { + VLOG_ERR("%s: port number must be specified", target_); + error = EAFNOSUPPORT; + goto exit; } /* Parse optional bind IP. */ @@ -466,6 +466,24 @@ exit: return error ? -error : fd; } +/* Returns a readable and writable fd for /dev/null, if successful, otherwise + * a negative errno value. The caller must not close the returned fd (because + * the same fd will be handed out to subsequent callers). */ +int +get_null_fd(void) +{ + static int null_fd = -1; + if (null_fd < 0) { + null_fd = open("/dev/null", O_RDWR); + if (null_fd < 0) { + int error = errno; + VLOG_ERR("could not open /dev/null: %s", strerror(error)); + return -error; + } + } + return null_fd; +} + int read_fully(int fd, void *p_, size_t size, size_t *bytes_read) {