Postfix3.3.1
myaddrinfo.h
[詳解]
1 #ifndef _MYADDRINFO_H_INCLUDED_
2 #define _MYADDRINFO_H_INCLUDED_
3 
4 /*++
5 /* NAME
6 /* myaddrinfo 3h
7 /* SUMMARY
8 /* addrinfo encapsulation and emulation
9 /* SYNOPSIS
10 /* #include <myaddrinfo.h>
11 /* DESCRIPTION
12 /* .nf
13 
14  /*
15  * System library.
16  */
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <netdb.h>
21 #include <string.h>
22 #include <errno.h> /* MAI_STRERROR() */
23 #include <limits.h> /* CHAR_BIT */
24 
25  /*
26  * Backwards compatibility support for IPV4 systems without addrinfo API.
27  */
28 #ifdef EMULATE_IPV4_ADDRINFO
29 
30  /*
31  * Avoid clashes with global symbols, just in case some third-party library
32  * provides its own addrinfo() implementation. This also allows us to test
33  * the IPV4 emulation code on an IPV6 enabled system.
34  */
35 #undef freeaddrinfo
36 #define freeaddrinfo mai_freeaddrinfo
37 #undef gai_strerror
38 #define gai_strerror mai_strerror
39 #undef addrinfo
40 #define addrinfo mai_addrinfo
41 #undef sockaddr_storage
42 #define sockaddr_storage mai_sockaddr_storage
43 
44  /*
45  * Modern systems define this in <netdb.h>.
46  */
47 struct addrinfo {
48  int ai_flags; /* AI_PASSIVE|CANONNAME|NUMERICHOST */
49  int ai_family; /* PF_xxx */
50  int ai_socktype; /* SOCK_xxx */
51  int ai_protocol; /* 0 or IPPROTO_xxx */
52  size_t ai_addrlen; /* length of ai_addr */
53  char *ai_canonname; /* canonical name for nodename */
54  struct sockaddr *ai_addr; /* binary address */
55  struct addrinfo *ai_next; /* next structure in linked list */
56 };
57 
58  /*
59  * Modern systems define this in <sys/socket.h>.
60  */
61 struct sockaddr_storage {
62  struct sockaddr_in dummy; /* alignment!! */
63 };
64 
65  /*
66  * Result codes. See gai_strerror() for text. Undefine already imported
67  * definitions so that we can test the IPv4-only emulation on a modern
68  * system without getting a ton of compiler warnings.
69  */
70 #undef EAI_ADDRFAMILY
71 #define EAI_ADDRFAMILY 1
72 #undef EAI_AGAIN
73 #define EAI_AGAIN 2
74 #undef EAI_BADFLAGS
75 #define EAI_BADFLAGS 3
76 #undef EAI_FAIL
77 #define EAI_FAIL 4
78 #undef EAI_FAMILY
79 #define EAI_FAMILY 5
80 #undef EAI_MEMORY
81 #define EAI_MEMORY 6
82 #undef EAI_NODATA
83 #define EAI_NODATA 7
84 #undef EAI_NONAME
85 #define EAI_NONAME 8
86 #undef EAI_SERVICE
87 #define EAI_SERVICE 9
88 #undef EAI_SOCKTYPE
89 #define EAI_SOCKTYPE 10
90 #undef EAI_SYSTEM
91 #define EAI_SYSTEM 11
92 #undef EAI_BADHINTS
93 #define EAI_BADHINTS 12
94 #undef EAI_PROTOCOL
95 #define EAI_PROTOCOL 13
96 #undef EAI_RESNULL
97 #define EAI_RESNULL 14
98 #undef EAI_MAX
99 #define EAI_MAX 15
100 
101 extern void freeaddrinfo(struct addrinfo *);
102 extern char *gai_strerror(int);
103 
104 #endif
105 
106  /*
107  * Bounds grow in leaps. These macros attempt to keep non-library code free
108  * from IPV6 #ifdef pollution. Avoid macro names that end in STRLEN because
109  * they suggest that space for the null terminator is not included.
110  */
111 #ifdef HAS_IPV6
112 # define MAI_HOSTADDR_STRSIZE INET6_ADDRSTRLEN
113 #else
114 # ifndef INET_ADDRSTRLEN
115 # define INET_ADDRSTRLEN 16
116 # endif
117 # define MAI_HOSTADDR_STRSIZE INET_ADDRSTRLEN
118 #endif
119 
120 #define MAI_HOSTNAME_STRSIZE 1025
121 #define MAI_SERVNAME_STRSIZE 32
122 #define MAI_SERVPORT_STRSIZE sizeof("65535")
123 
124 #define MAI_V4ADDR_BITS 32
125 #define MAI_V6ADDR_BITS 128
126 #define MAI_V4ADDR_BYTES ((MAI_V4ADDR_BITS + (CHAR_BIT - 1))/CHAR_BIT)
127 #define MAI_V6ADDR_BYTES ((MAI_V6ADDR_BITS + (CHAR_BIT - 1))/CHAR_BIT)
128 
129  /*
130  * Routines and data structures to hide some of the complexity of the
131  * addrinfo API. They still don't hide that we may get results for address
132  * families that we aren't interested in.
133  *
134  * Note: the getnameinfo() and inet_ntop() system library functions use unsafe
135  * APIs with separate pointer and length arguments. To avoid buffer overflow
136  * problems with these functions, Postfix uses pointers to structures
137  * internally. This way the compiler can enforce that callers provide
138  * buffers with the appropriate length, instead of having to trust that
139  * callers will never mess up some length calculation.
140  */
141 typedef struct {
144 
145 typedef struct {
148 
149 typedef struct {
152 
153 typedef struct {
156 
157 extern int WARN_UNUSED_RESULT hostname_to_sockaddr_pf(const char *,
158  int, const char *, int, struct addrinfo **);
159 extern int WARN_UNUSED_RESULT hostaddr_to_sockaddr(const char *,
160  const char *, int, struct addrinfo **);
161 extern int WARN_UNUSED_RESULT sockaddr_to_hostaddr(const struct sockaddr *,
163 extern int WARN_UNUSED_RESULT sockaddr_to_hostname(const struct sockaddr *,
165 extern void myaddrinfo_control(int,...);
166 
167 #define MAI_CTL_END 0 /* list terminator */
168 
169 #define MAI_STRERROR(e) ((e) == EAI_SYSTEM ? strerror(errno) : gai_strerror(e))
170 
171 #define hostname_to_sockaddr(host, serv, sock, res) \
172  hostname_to_sockaddr_pf((host), PF_UNSPEC, (serv), (sock), (res))
173 
174  /*
175  * Macros for the case where we really don't want to be bothered with things
176  * that may fail.
177  */
178 #define HOSTNAME_TO_SOCKADDR_PF(host, pf, serv, sock, res) \
179  do { \
180  int _aierr; \
181  _aierr = hostname_to_sockaddr_pf((host), (pf), (serv), (sock), (res)); \
182  if (_aierr) \
183  msg_fatal("hostname_to_sockaddr_pf: %s", MAI_STRERROR(_aierr)); \
184  } while (0)
185 
186 #define HOSTNAME_TO_SOCKADDR(host, serv, sock, res) \
187  HOSTNAME_TO_SOCKADDR_PF((host), PF_UNSPEC, (serv), (sock), (res))
188 
189 #define HOSTADDR_TO_SOCKADDR(host, serv, sock, res) \
190  do { \
191  int _aierr; \
192  _aierr = hostaddr_to_sockaddr((host), (serv), (sock), (res)); \
193  if (_aierr) \
194  msg_fatal("hostaddr_to_sockaddr: %s", MAI_STRERROR(_aierr)); \
195  } while (0)
196 
197 #define SOCKADDR_TO_HOSTADDR(sa, salen, host, port, sock) \
198  do { \
199  int _aierr; \
200  _aierr = sockaddr_to_hostaddr((sa), (salen), (host), (port), (sock)); \
201  if (_aierr) \
202  msg_fatal("sockaddr_to_hostaddr: %s", MAI_STRERROR(_aierr)); \
203  } while (0)
204 
205 #define SOCKADDR_TO_HOSTNAME(sa, salen, host, service, sock) \
206  do { \
207  int _aierr; \
208  _aierr = sockaddr_to_hostname((sa), (salen), (host), (service), (sock)); \
209  if (_aierr) \
210  msg_fatal("sockaddr_to_hostname: %s", MAI_STRERROR(_aierr)); \
211  } while (0)
212 
213 /* LICENSE
214 /* .ad
215 /* .fi
216 /* The Secure Mailer license must be distributed with this software.
217 /* AUTHOR(S)
218 /* Wietse Venema
219 /* IBM T.J. Watson Research
220 /* P.O. Box 704
221 /* Yorktown Heights, NY 10598, USA
222 /*
223 /* Wietse Venema
224 /* Google, Inc.
225 /* 111 8th Avenue
226 /* New York, NY 10011, USA
227 /*--*/
228 
229 #endif
void freeaddrinfo(struct addrinfo *ai)
Definition: myaddrinfo.c:742
int WARN_UNUSED_RESULT sockaddr_to_hostname(const struct sockaddr *, SOCKADDR_SIZE, MAI_HOSTNAME_STR *, MAI_SERVNAME_STR *, int)
Definition: myaddrinfo.c:631
void myaddrinfo_control(int,...)
Definition: myaddrinfo.c:724
#define SOCKADDR_SIZE
Definition: sys_defs.h:1411
int WARN_UNUSED_RESULT sockaddr_to_hostaddr(const struct sockaddr *, SOCKADDR_SIZE, MAI_HOSTADDR_STR *, MAI_SERVPORT_STR *, int)
Definition: myaddrinfo.c:580
#define MAI_HOSTNAME_STRSIZE
Definition: myaddrinfo.h:120
#define WARN_UNUSED_RESULT
Definition: sys_defs.h:1662
int WARN_UNUSED_RESULT hostaddr_to_sockaddr(const char *, const char *, int, struct addrinfo **)
Definition: myaddrinfo.c:464
int WARN_UNUSED_RESULT hostname_to_sockaddr_pf(const char *, int, const char *, int, struct addrinfo **)
Definition: myaddrinfo.c:295
#define MAI_SERVNAME_STRSIZE
Definition: myaddrinfo.h:121
#define MAI_SERVPORT_STRSIZE
Definition: myaddrinfo.h:122
char * gai_strerror(int ecode)
Definition: myaddrinfo.c:779
#define MAI_HOSTADDR_STRSIZE
Definition: myaddrinfo.h:117