summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLAN-TW <lantw44@gmail.com>2013-12-21 00:07:27 +0800
committerLAN-TW <lantw44@gmail.com>2013-12-21 00:07:27 +0800
commit36f00fbd5aee43a564d5932a6a9c2956c4ab24cc (patch)
treee13b2c8a4dfcabea53f86801f7d5632366fc9bf2
parentec5ac2e9141ac6e7230ad97720c286c2e1b4c18a (diff)
downloadcn2013-36f00fbd5aee43a564d5932a6a9c2956c4ab24cc.tar.gz
cn2013-36f00fbd5aee43a564d5932a6a9c2956c4ab24cc.tar.zst
cn2013-36f00fbd5aee43a564d5932a6a9c2956c4ab24cc.zip
HW2: 加入 getaddrinfo 共用 wrapper
-rw-r--r--hw2/Makefile.am1
-rw-r--r--hw2/agent-main.c36
-rw-r--r--hw2/l4logger.c2
-rw-r--r--hw2/ump-common.h4
-rw-r--r--hw2/ump-gai.c85
-rw-r--r--hw2/ump-gai.h15
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 */