diff options
author | LAN-TW <lantw44@gmail.com> | 2013-12-21 00:07:27 +0800 |
---|---|---|
committer | LAN-TW <lantw44@gmail.com> | 2013-12-21 00:07:27 +0800 |
commit | 36f00fbd5aee43a564d5932a6a9c2956c4ab24cc (patch) | |
tree | e13b2c8a4dfcabea53f86801f7d5632366fc9bf2 | |
parent | ec5ac2e9141ac6e7230ad97720c286c2e1b4c18a (diff) | |
download | cn2013-36f00fbd5aee43a564d5932a6a9c2956c4ab24cc.tar.gz cn2013-36f00fbd5aee43a564d5932a6a9c2956c4ab24cc.tar.zst cn2013-36f00fbd5aee43a564d5932a6a9c2956c4ab24cc.zip |
HW2: 加入 getaddrinfo 共用 wrapper
-rw-r--r-- | hw2/Makefile.am | 1 | ||||
-rw-r--r-- | hw2/agent-main.c | 36 | ||||
-rw-r--r-- | hw2/l4logger.c | 2 | ||||
-rw-r--r-- | hw2/ump-common.h | 4 | ||||
-rw-r--r-- | hw2/ump-gai.c | 85 | ||||
-rw-r--r-- | hw2/ump-gai.h | 15 |
6 files changed, 138 insertions, 5 deletions
diff --git a/hw2/Makefile.am b/hw2/Makefile.am index f63533f..16a58ca 100644 --- a/hw2/Makefile.am +++ b/hw2/Makefile.am @@ -12,6 +12,7 @@ liblbs_a_SOURCES = \ libump_a_SOURCES = \ ump-common.h ump-app.h \ + ump-gai.c ump-gai.h \ ump-pkt.c ump-pkt.h \ $(NULL) diff --git a/hw2/agent-main.c b/hw2/agent-main.c index 9db9294..2e5b251 100644 --- a/hw2/agent-main.c +++ b/hw2/agent-main.c @@ -3,20 +3,48 @@ #endif #include "l4logger.h" +#include "ump-gai.h" +#include <errno.h> #include <locale.h> +#include <stdio.h> +#include <string.h> #include <time.h> int main (int argc, char* argv[]) { setlocale (LC_ALL, ""); tzset (); - LbsLogger lbs_log_struct; - LbsLogger* lbs_log = &lbs_log_struct; - lbs_logger_init (lbs_log, LBS_LOGGER_FILE_STDOUT, LBS_LOGGER_COLOR_AUTO, + if (argc < 3) { + fprintf (stderr, "Usage: %s bind_host bind_port\n", argv[0]); + return 1; + } + + LbsLogger agent_log_struct; + LbsLogger* agent_log = &agent_log_struct; + lbs_logger_init (agent_log, LBS_LOGGER_FILE_STDOUT, LBS_LOGGER_COLOR_AUTO, argv[0], "UMP_AGENT_FILE", "UMP_AGENT_COLOR"); - lbs_logger_destroy (lbs_log); + struct addrinfo gai_hints; + memset (&gai_hints, 0, sizeof (gai_hints)); + gai_hints.ai_family = AF_UNSPEC; + gai_hints.ai_socktype = SOCK_DGRAM; + gai_hints.ai_flags = AI_ADDRCONFIG; + + int gai_errno; + int udp_fd = ump_gai (agent_log, argv[1], argv[2], &gai_hints, &gai_errno); + if (udp_fd < 0) { + if (gai_errno) { + fprintf (stderr, "%s: %s\n", argv[0], gai_strerror (gai_errno)); + } else { + fprintf (stderr, "%s: %s\n", argv[0], strerror (errno)); + } + return 2; + } + + + + lbs_logger_destroy (agent_log); return 0; } diff --git a/hw2/l4logger.c b/hw2/l4logger.c index 4430c99..654acf5 100644 --- a/hw2/l4logger.c +++ b/hw2/l4logger.c @@ -146,7 +146,7 @@ void lbs_logger_init (LbsLogger* lbs_log, int default_file, int default_color, } void lbs_logger_destroy (LbsLogger* lbs_log) { - if (!lbs_log->enabled) { + if (lbs_log == NULL || !lbs_log->enabled) { return; } diff --git a/hw2/ump-common.h b/hw2/ump-common.h index 399cf82..0457f88 100644 --- a/hw2/ump-common.h +++ b/hw2/ump-common.h @@ -5,6 +5,10 @@ #include <stdint.h> #include <string.h> +/* Common macro without namespace */ +#define SOCKADDR_IN(x) ((struct sockaddr_in*)(x)) +#define SOCKADDR_IN6(x) ((struct sockaddr_in6*)(x)) + static inline void ump_common_copy ( void* dest, const void* src, size_t len) { diff --git a/hw2/ump-gai.c b/hw2/ump-gai.c new file mode 100644 index 0000000..74a3cae --- /dev/null +++ b/hw2/ump-gai.c @@ -0,0 +1,85 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ump-gai.h" +#include "ump-common.h" +#include "xwrap.h" +#include "l4logger.h" + +#include <arpa/inet.h> +#include <errno.h> +#include <inttypes.h> +#include <netdb.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <unistd.h> + +int ump_gai (LbsLogger* lbs_log, const char* host, const char* port, + const struct addrinfo* hints, int *error) { + + lbs_logger_format (lbs_log, "getaddrinfo: host %s, port %s",host, port); + + struct addrinfo* result; + int gai_errno = getaddrinfo (host, port, hints, &result); + if (gai_errno != 0) { + lbs_logger_format (lbs_log, "getaddrinfo: %s", gai_strerror (gai_errno)); + *error = gai_errno; + return -1; + } + + for (struct addrinfo* iter = result; iter != NULL; iter = iter->ai_next) { + int sockfd = socket (iter->ai_family, SOCK_DGRAM, 0); + if (sockfd < 0) { + freeaddrinfo (result); + lbs_logger_format (lbs_log, "socket: %s", strerror (errno)); + *error = 0; + return -1; + } + + if (iter->ai_family == AF_INET6) { + lbs_logger_string (lbs_log, "host address is IPv6"); + } else { + lbs_logger_string (lbs_log, "host address is IPv4"); + } + + size_t ip_str_len = xmax (INET_ADDRSTRLEN, INET6_ADDRSTRLEN); + char* ip_str = xmalloc (ip_str_len); + uint16_t udp_port = ntohs ( + iter->ai_family == AF_INET6 ? + SOCKADDR_IN6 (iter->ai_addr)->sin6_port : + SOCKADDR_IN (iter->ai_addr)->sin_port); + + if (inet_ntop (iter->ai_family, + iter->ai_family == AF_INET6 ? + (void*) &SOCKADDR_IN6 (iter->ai_addr)->sin6_addr : + (void*) &SOCKADDR_IN (iter->ai_addr)->sin_addr, + ip_str, ip_str_len) == NULL) { + + lbs_logger_format (lbs_log, + "bind to unknown host, port %" PRIu16, udp_port); + } else { + lbs_logger_format (lbs_log, + "bind to host %s, port %" PRIu16, ip_str, udp_port); + } + + free (ip_str); + + if (bind (sockfd, iter->ai_addr, iter->ai_addrlen) < 0) { + lbs_logger_format (lbs_log, "bind: %s", strerror (errno)); + close (sockfd); + } else { + lbs_logger_string (lbs_log, "bind OK"); + freeaddrinfo (result); + return sockfd; + } + } + + if (result != NULL) { + freeaddrinfo (result); + } + + *error = 0; + return -1; +} diff --git a/hw2/ump-gai.h b/hw2/ump-gai.h new file mode 100644 index 0000000..6d6ba25 --- /dev/null +++ b/hw2/ump-gai.h @@ -0,0 +1,15 @@ +#ifndef UMP_GAI_H +#define UMP_GAI_H + +/* getaddrinfo(3) wrapper */ + +#include "l4logger.h" + +#include <netdb.h> +#include <sys/types.h> +#include <sys/socket.h> + +int ump_gai (LbsLogger* lbs_log, const char* host, const char* port, + const struct addrinfo* hints, int *error); + +#endif /* UMP_GAI_H */ |