-
Notifications
You must be signed in to change notification settings - Fork 0
/
conn.h
150 lines (134 loc) · 8.8 KB
/
conn.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/* Mark Jia, mij623, 11271998 */
#ifndef _CONN_H_
#define _CONN_H_
#include <netdb.h>
#define CONNMACRO
#define handle_error_en(en, msg) \
do { \
errno = en; \
perror(msg); \
exit(EXIT_FAILURE); \
} while (0)
#define handle_error(msg) \
do { \
perror(msg); \
exit(EXIT_FAILURE); \
} while (0)
/* a collection of macros that are useful for this datagram prog */
#define do_setup_hints(s, c, n, e) \
do { \
if (memset(&(s), (c), (n)) == NULL) \
handle_error((e)); \
s.ai_family = AF_INET; /* IPv4 */ \
s.ai_socktype = SOCK_DGRAM; /* UDP (datagram) */ \
} while (0)
/* temp, sendName, sendPort, hints, servinfo */
#define do_getaddrinfo(t, n, p, h, s) \
do { \
if (((t) = getaddrinfo((n), (p), &(h), &(s))) != 0) { \
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(t)); \
exit(EXIT_FAILURE); \
} \
} while (0)
/* p, servinfo, sockfd */
#define do_socket_walk(p, s, f, e) \
do { \
for ((p) = (s); (p) != NULL; (p) = (p)->ai_next) { \
(f) = socket((p)->ai_family, (p)->ai_socktype, (p)->ai_protocol); \
if ((f) < 0) { \
perror("socket"); \
continue; \
} \
break; \
} \
\
if ((p) == NULL) { /* if no socket is created */ \
fprintf(stderr, "%s: failed to create socket\n", (e)); \
exit(EXIT_FAILURE); \
} \
} while (0)
/* from p to sendto addr */
#define do_p_to_sin_addr(p, a) \
do { \
(a) = (((struct sockaddr_in *)(p)->ai_addr)->sin_addr).s_addr; \
} while (0)
/* from `struct sockaddr_storage` to sendto addr */
#define do_saddrsto_to_sin_addr(s, a) \
do { \
(a) = (((struct sockaddr_in *)(&(s)))->sin_addr).s_addr; \
} while (0)
/* given the addr part of ChannelMsg and 2 addrinfo,
* find one that the message should go.
* (if from==p_i->sin_addr, then return p_j)
* */
#define do_find_msgDest_addrinfo(f, p, q, r) \
do { \
if ((f) == (p)) \
(r) = (q); \
else \
(r) = (p); \
} while (0)
#define do_sendto(sock, msg, p, done) \
do { \
numbytes = \
sendto((sock), (msg), strlen(msg), 0, (p)->ai_addr, (p)->ai_addrlen); \
if (numbytes < 0) { \
perror("sendto"); \
hasProblemo = true; \
(done) = true; \
} \
} while (0)
#define do_sender_findHS(p, hbuf, sbuf) \
do { \
if (getnameinfo((p)->ai_addr, (p)->ai_addrlen, (hbuf), sizeof((hbuf)), \
(sbuf), sizeof((sbuf)), \
NI_NUMERICHOST | NI_NUMERICSERV) != 0) { \
fprintf(stderr, "getnameinfo: %s\n", gai_strerror(errno)); \
exit(EXIT_FAILURE); \
} \
} while (0)
#define do_testkill(msg, kill, done) \
do { \
if (!(done)) { \
if (!((done) |= (strcmp((msg), (kill)) == 0))) /* if not same string */ \
(done) |= ((strncmp((msg), (kill), strlen((kill))) == 0) && \
(strlen((msg)) - strlen((msg)) == 1) && \
((msg)[strlen((kill))] == '\n')); \
} \
} while (0)
#define do_free_msg(m) \
do { \
free((m)->msg); \
free((m)); \
} while (0)
#define do_done_cleanup(servinfo, sockfd) \
do { \
freeaddrinfo((servinfo)); \
close((sockfd)); \
} while (0)
#define do_done_send_print(nMsg, who) \
do { \
printf("send_thread: sent " INT_FMT "messages to %s \n", (nMsg), (who)); \
printf("send_thread: stream to %s is done, socket has closed\n", (who)); \
} while (0)
#define gen_rand(ret) \
do { \
(ret) = (float)rand() / (float)(RAND_MAX + 1.0); \
} while (0)
#define do_getSockFdFromRemoteSto(rAddr, rIP, s) \
do { \
(s) = \
inet_ntop((rAddr).ss_family, get_in_addr((struct sockaddr *)&(rAddr), \
(rIP), INET6_ADDRSTRLEN)) \
} while (0)
#define do_getnameinfo(sa, sal, bhst, bsrv) \
do { \
if (getnameinfo((sa), (sal), (bhst), NI_MAXHOST, (bsrv), NI_MAXSERV, \
NI_NUMERICHOST | NI_NUMERICSERV) != 0) { \
fprintf(stderr, "getnameinfo: %s\n", gai_strerror(errno)); \
fprintf(stderr, "info: sockaddr:%p socklen_t:%d, host:%s, serv:%s\n", \
(void *)(sa), (sal), (bhst), (bsrv)); \
exit(EXIT_FAILURE); \
} \
} while (0)
#endif /* _CONN_H_ */