File: | rpc/rpc-transport/socket/src/name.c |
Location: | line 421, column 31 |
Description: | Access to field 'ai_addr' results in a dereference of a null pointer (loaded from variable 'res') |
1 | /* | |||
2 | Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> | |||
3 | This file is part of GlusterFS. | |||
4 | ||||
5 | This file is licensed to you under your choice of the GNU Lesser | |||
6 | General Public License, version 3 or any later version (LGPLv3 or | |||
7 | later), or the GNU General Public License, version 2 (GPLv2), in all | |||
8 | cases as published by the Free Software Foundation. | |||
9 | */ | |||
10 | ||||
11 | #include <sys/types.h> | |||
12 | #include <sys/socket.h> | |||
13 | #include <netinet/in.h> | |||
14 | #include <errno(*__errno_location ()).h> | |||
15 | #include <netdb.h> | |||
16 | #include <string.h> | |||
17 | ||||
18 | #ifndef AF_INET_SDP27 | |||
19 | #define AF_INET_SDP27 27 | |||
20 | #endif | |||
21 | ||||
22 | #include "rpc-transport.h" | |||
23 | #include "socket.h" | |||
24 | #include "common-utils.h" | |||
25 | ||||
26 | int32_t | |||
27 | gf_resolve_ip6 (const char *hostname, | |||
28 | uint16_t port, | |||
29 | int family, | |||
30 | void **dnscache, | |||
31 | struct addrinfo **addr_info); | |||
32 | ||||
33 | static int32_t | |||
34 | af_inet_bind_to_port_lt_ceiling (int fd, struct sockaddr *sockaddr, | |||
35 | socklen_t sockaddr_len, int ceiling) | |||
36 | { | |||
37 | int32_t ret = -1; | |||
38 | uint16_t port = ceiling - 1; | |||
39 | // by default assume none of the ports are blocked and all are available | |||
40 | gf_boolean_t ports[1024] = {_gf_false,}; | |||
41 | int i = 0; | |||
42 | ||||
43 | ret = gf_process_reserved_ports (ports); | |||
44 | if (ret != 0) { | |||
45 | for (i = 0; i < 1024; i++) | |||
46 | ports[i] = _gf_false; | |||
47 | } | |||
48 | ||||
49 | while (port) | |||
50 | { | |||
51 | switch (sockaddr->sa_family) | |||
52 | { | |||
53 | case AF_INET610: | |||
54 | ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons (port); | |||
55 | break; | |||
56 | ||||
57 | case AF_INET_SDP27: | |||
58 | case AF_INET2: | |||
59 | ((struct sockaddr_in *)sockaddr)->sin_port = htons (port); | |||
60 | break; | |||
61 | } | |||
62 | // ignore the reserved ports | |||
63 | if (ports[port] == _gf_true) { | |||
64 | port--; | |||
65 | continue; | |||
66 | } | |||
67 | ret = bind (fd, sockaddr, sockaddr_len); | |||
68 | ||||
69 | if (ret == 0) | |||
70 | break; | |||
71 | ||||
72 | if (ret == -1 && errno(*__errno_location ()) == EACCES13) | |||
73 | break; | |||
74 | ||||
75 | port--; | |||
76 | } | |||
77 | ||||
78 | return ret; | |||
79 | } | |||
80 | ||||
81 | static int32_t | |||
82 | af_unix_client_bind (rpc_transport_t *this, | |||
83 | struct sockaddr *sockaddr, | |||
84 | socklen_t sockaddr_len, | |||
85 | int sock) | |||
86 | { | |||
87 | data_t *path_data = NULL((void*)0); | |||
88 | struct sockaddr_un *addr = NULL((void*)0); | |||
89 | int32_t ret = 0; | |||
90 | ||||
91 | path_data = dict_get (this->options, "transport.socket.bind-path"); | |||
92 | if (path_data) { | |||
93 | char *path = data_to_str (path_data); | |||
94 | if (!path || strlen (path) > UNIX_PATH_MAX108) { | |||
95 | gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("bind-path not specified for unix socket, " "letting connect to assign default value"); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 97, GF_LOG_TRACE, "bind-path not specified for unix socket, " "letting connect to assign default value"); } while (0) | |||
96 | "bind-path not specified for unix socket, "do { do { if (0) printf ("bind-path not specified for unix socket, " "letting connect to assign default value"); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 97, GF_LOG_TRACE, "bind-path not specified for unix socket, " "letting connect to assign default value"); } while (0) | |||
97 | "letting connect to assign default value")do { do { if (0) printf ("bind-path not specified for unix socket, " "letting connect to assign default value"); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 97, GF_LOG_TRACE, "bind-path not specified for unix socket, " "letting connect to assign default value"); } while (0); | |||
98 | goto err; | |||
99 | } | |||
100 | ||||
101 | addr = (struct sockaddr_un *) sockaddr; | |||
102 | strcpy (addr->sun_path, path); | |||
103 | ret = bind (sock, (struct sockaddr *)addr, sockaddr_len); | |||
104 | if (ret == -1) { | |||
105 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("cannot bind to unix-domain socket %d (%s)" , sock, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 107, GF_LOG_ERROR, "cannot bind to unix-domain socket %d (%s)" , sock, strerror ((*__errno_location ()))); } while (0) | |||
106 | "cannot bind to unix-domain socket %d (%s)",do { do { if (0) printf ("cannot bind to unix-domain socket %d (%s)" , sock, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 107, GF_LOG_ERROR, "cannot bind to unix-domain socket %d (%s)" , sock, strerror ((*__errno_location ()))); } while (0) | |||
107 | sock, strerror (errno))do { do { if (0) printf ("cannot bind to unix-domain socket %d (%s)" , sock, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 107, GF_LOG_ERROR, "cannot bind to unix-domain socket %d (%s)" , sock, strerror ((*__errno_location ()))); } while (0); | |||
108 | goto err; | |||
109 | } | |||
110 | } else { | |||
111 | gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("bind-path not specified for unix socket, " "letting connect to assign default value"); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 113, GF_LOG_TRACE, "bind-path not specified for unix socket, " "letting connect to assign default value"); } while (0) | |||
112 | "bind-path not specified for unix socket, "do { do { if (0) printf ("bind-path not specified for unix socket, " "letting connect to assign default value"); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 113, GF_LOG_TRACE, "bind-path not specified for unix socket, " "letting connect to assign default value"); } while (0) | |||
113 | "letting connect to assign default value")do { do { if (0) printf ("bind-path not specified for unix socket, " "letting connect to assign default value"); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 113, GF_LOG_TRACE, "bind-path not specified for unix socket, " "letting connect to assign default value"); } while (0); | |||
114 | } | |||
115 | ||||
116 | err: | |||
117 | return ret; | |||
118 | } | |||
119 | ||||
120 | int32_t | |||
121 | client_fill_address_family (rpc_transport_t *this, sa_family_t *sa_family) | |||
122 | { | |||
123 | data_t *address_family_data = NULL((void*)0); | |||
124 | int32_t ret = -1; | |||
125 | ||||
126 | if (sa_family == NULL((void*)0)) { | |||
127 | gf_log_callingfn ("", GF_LOG_WARNING,do { do { if (0) printf ("sa_family argument is NULL"); } while (0); _gf_log_callingfn ("", "name.c", __FUNCTION__, 128, GF_LOG_WARNING , "sa_family argument is NULL"); } while (0) | |||
128 | "sa_family argument is NULL")do { do { if (0) printf ("sa_family argument is NULL"); } while (0); _gf_log_callingfn ("", "name.c", __FUNCTION__, 128, GF_LOG_WARNING , "sa_family argument is NULL"); } while (0); | |||
129 | goto out; | |||
130 | } | |||
131 | ||||
132 | address_family_data = dict_get (this->options, | |||
133 | "transport.address-family"); | |||
134 | if (!address_family_data) { | |||
135 | data_t *remote_host_data = NULL((void*)0), *connect_path_data = NULL((void*)0); | |||
136 | remote_host_data = dict_get (this->options, "remote-host"); | |||
137 | connect_path_data = dict_get (this->options, | |||
138 | "transport.socket.connect-path"); | |||
139 | ||||
140 | if (!(remote_host_data || connect_path_data) || | |||
141 | (remote_host_data && connect_path_data)) { | |||
142 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("transport.address-family not specified. " "Could not guess default value from (remote-host:%s or " "transport.unix.connect-path:%s) options" , data_to_str (remote_host_data), data_to_str (connect_path_data )); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 147, GF_LOG_ERROR, "transport.address-family not specified. " "Could not guess default value from (remote-host:%s or " "transport.unix.connect-path:%s) options" , data_to_str (remote_host_data), data_to_str (connect_path_data )); } while (0) | |||
143 | "transport.address-family not specified. "do { do { if (0) printf ("transport.address-family not specified. " "Could not guess default value from (remote-host:%s or " "transport.unix.connect-path:%s) options" , data_to_str (remote_host_data), data_to_str (connect_path_data )); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 147, GF_LOG_ERROR, "transport.address-family not specified. " "Could not guess default value from (remote-host:%s or " "transport.unix.connect-path:%s) options" , data_to_str (remote_host_data), data_to_str (connect_path_data )); } while (0) | |||
144 | "Could not guess default value from (remote-host:%s or "do { do { if (0) printf ("transport.address-family not specified. " "Could not guess default value from (remote-host:%s or " "transport.unix.connect-path:%s) options" , data_to_str (remote_host_data), data_to_str (connect_path_data )); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 147, GF_LOG_ERROR, "transport.address-family not specified. " "Could not guess default value from (remote-host:%s or " "transport.unix.connect-path:%s) options" , data_to_str (remote_host_data), data_to_str (connect_path_data )); } while (0) | |||
145 | "transport.unix.connect-path:%s) options",do { do { if (0) printf ("transport.address-family not specified. " "Could not guess default value from (remote-host:%s or " "transport.unix.connect-path:%s) options" , data_to_str (remote_host_data), data_to_str (connect_path_data )); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 147, GF_LOG_ERROR, "transport.address-family not specified. " "Could not guess default value from (remote-host:%s or " "transport.unix.connect-path:%s) options" , data_to_str (remote_host_data), data_to_str (connect_path_data )); } while (0) | |||
146 | data_to_str (remote_host_data),do { do { if (0) printf ("transport.address-family not specified. " "Could not guess default value from (remote-host:%s or " "transport.unix.connect-path:%s) options" , data_to_str (remote_host_data), data_to_str (connect_path_data )); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 147, GF_LOG_ERROR, "transport.address-family not specified. " "Could not guess default value from (remote-host:%s or " "transport.unix.connect-path:%s) options" , data_to_str (remote_host_data), data_to_str (connect_path_data )); } while (0) | |||
147 | data_to_str (connect_path_data))do { do { if (0) printf ("transport.address-family not specified. " "Could not guess default value from (remote-host:%s or " "transport.unix.connect-path:%s) options" , data_to_str (remote_host_data), data_to_str (connect_path_data )); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 147, GF_LOG_ERROR, "transport.address-family not specified. " "Could not guess default value from (remote-host:%s or " "transport.unix.connect-path:%s) options" , data_to_str (remote_host_data), data_to_str (connect_path_data )); } while (0); | |||
148 | *sa_family = AF_UNSPEC0; | |||
149 | goto out; | |||
150 | } | |||
151 | ||||
152 | if (remote_host_data) { | |||
153 | gf_log (this->name, GF_LOG_DEBUG,do { do { if (0) printf ("address-family not specified, guessing it " "to be inet from (remote-host: %s)", data_to_str (remote_host_data )); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 155, GF_LOG_DEBUG, "address-family not specified, guessing it " "to be inet from (remote-host: %s)", data_to_str (remote_host_data )); } while (0) | |||
154 | "address-family not specified, guessing it "do { do { if (0) printf ("address-family not specified, guessing it " "to be inet from (remote-host: %s)", data_to_str (remote_host_data )); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 155, GF_LOG_DEBUG, "address-family not specified, guessing it " "to be inet from (remote-host: %s)", data_to_str (remote_host_data )); } while (0) | |||
155 | "to be inet from (remote-host: %s)", data_to_str (remote_host_data))do { do { if (0) printf ("address-family not specified, guessing it " "to be inet from (remote-host: %s)", data_to_str (remote_host_data )); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 155, GF_LOG_DEBUG, "address-family not specified, guessing it " "to be inet from (remote-host: %s)", data_to_str (remote_host_data )); } while (0); | |||
156 | *sa_family = AF_INET2; | |||
157 | } else { | |||
158 | gf_log (this->name, GF_LOG_DEBUG,do { do { if (0) printf ("address-family not specified, guessing it " "to be unix from (transport.unix.connect-path: %s)", data_to_str (connect_path_data)); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 160, GF_LOG_DEBUG, "address-family not specified, guessing it " "to be unix from (transport.unix.connect-path: %s)", data_to_str (connect_path_data)); } while (0) | |||
159 | "address-family not specified, guessing it "do { do { if (0) printf ("address-family not specified, guessing it " "to be unix from (transport.unix.connect-path: %s)", data_to_str (connect_path_data)); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 160, GF_LOG_DEBUG, "address-family not specified, guessing it " "to be unix from (transport.unix.connect-path: %s)", data_to_str (connect_path_data)); } while (0) | |||
160 | "to be unix from (transport.unix.connect-path: %s)", data_to_str (connect_path_data))do { do { if (0) printf ("address-family not specified, guessing it " "to be unix from (transport.unix.connect-path: %s)", data_to_str (connect_path_data)); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 160, GF_LOG_DEBUG, "address-family not specified, guessing it " "to be unix from (transport.unix.connect-path: %s)", data_to_str (connect_path_data)); } while (0); | |||
161 | *sa_family = AF_UNIX1; | |||
162 | } | |||
163 | ||||
164 | } else { | |||
165 | char *address_family = data_to_str (address_family_data); | |||
166 | if (!strcasecmp (address_family, "unix")) { | |||
167 | *sa_family = AF_UNIX1; | |||
168 | } else if (!strcasecmp (address_family, "inet")) { | |||
169 | *sa_family = AF_INET2; | |||
170 | } else if (!strcasecmp (address_family, "inet6")) { | |||
171 | *sa_family = AF_INET610; | |||
172 | } else if (!strcasecmp (address_family, "inet-sdp")) { | |||
173 | *sa_family = AF_INET_SDP27; | |||
174 | } else { | |||
175 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("unknown address-family (%s) specified" , address_family); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 177, GF_LOG_ERROR, "unknown address-family (%s) specified" , address_family); } while (0) | |||
176 | "unknown address-family (%s) specified",do { do { if (0) printf ("unknown address-family (%s) specified" , address_family); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 177, GF_LOG_ERROR, "unknown address-family (%s) specified" , address_family); } while (0) | |||
177 | address_family)do { do { if (0) printf ("unknown address-family (%s) specified" , address_family); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 177, GF_LOG_ERROR, "unknown address-family (%s) specified" , address_family); } while (0); | |||
178 | *sa_family = AF_UNSPEC0; | |||
179 | goto out; | |||
180 | } | |||
181 | } | |||
182 | ||||
183 | ret = 0; | |||
184 | ||||
185 | out: | |||
186 | return ret; | |||
187 | } | |||
188 | ||||
189 | static int32_t | |||
190 | af_inet_client_get_remote_sockaddr (rpc_transport_t *this, | |||
191 | struct sockaddr *sockaddr, | |||
192 | socklen_t *sockaddr_len) | |||
193 | { | |||
194 | dict_t *options = this->options; | |||
195 | data_t *remote_host_data = NULL((void*)0); | |||
196 | data_t *remote_port_data = NULL((void*)0); | |||
197 | char *remote_host = NULL((void*)0); | |||
198 | uint16_t remote_port = 0; | |||
199 | struct addrinfo *addr_info = NULL((void*)0); | |||
200 | int32_t ret = 0; | |||
201 | ||||
202 | remote_host_data = dict_get (options, "remote-host"); | |||
203 | if (remote_host_data == NULL((void*)0)) | |||
204 | { | |||
205 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("option remote-host missing in volume %s" , this->name); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 206, GF_LOG_ERROR, "option remote-host missing in volume %s" , this->name); } while (0) | |||
206 | "option remote-host missing in volume %s", this->name)do { do { if (0) printf ("option remote-host missing in volume %s" , this->name); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 206, GF_LOG_ERROR, "option remote-host missing in volume %s" , this->name); } while (0); | |||
207 | ret = -1; | |||
208 | goto err; | |||
209 | } | |||
210 | ||||
211 | remote_host = data_to_str (remote_host_data); | |||
212 | if (remote_host == NULL((void*)0)) | |||
213 | { | |||
214 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("option remote-host has data NULL in volume %s" , this->name); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 215, GF_LOG_ERROR, "option remote-host has data NULL in volume %s" , this->name); } while (0) | |||
215 | "option remote-host has data NULL in volume %s", this->name)do { do { if (0) printf ("option remote-host has data NULL in volume %s" , this->name); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 215, GF_LOG_ERROR, "option remote-host has data NULL in volume %s" , this->name); } while (0); | |||
216 | ret = -1; | |||
217 | goto err; | |||
218 | } | |||
219 | ||||
220 | remote_port_data = dict_get (options, "remote-port"); | |||
221 | if (remote_port_data == NULL((void*)0)) | |||
222 | { | |||
223 | gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("option remote-port missing in volume %s. Defaulting to %d" , this->name, 24007); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 225, GF_LOG_TRACE, "option remote-port missing in volume %s. Defaulting to %d" , this->name, 24007); } while (0) | |||
224 | "option remote-port missing in volume %s. Defaulting to %d",do { do { if (0) printf ("option remote-port missing in volume %s. Defaulting to %d" , this->name, 24007); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 225, GF_LOG_TRACE, "option remote-port missing in volume %s. Defaulting to %d" , this->name, 24007); } while (0) | |||
225 | this->name, GF_DEFAULT_SOCKET_LISTEN_PORT)do { do { if (0) printf ("option remote-port missing in volume %s. Defaulting to %d" , this->name, 24007); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 225, GF_LOG_TRACE, "option remote-port missing in volume %s. Defaulting to %d" , this->name, 24007); } while (0); | |||
226 | ||||
227 | remote_port = GF_DEFAULT_SOCKET_LISTEN_PORT24007; | |||
228 | } | |||
229 | else | |||
230 | { | |||
231 | remote_port = data_to_uint16 (remote_port_data); | |||
232 | } | |||
233 | ||||
234 | if (remote_port == (uint16_t)-1) | |||
235 | { | |||
236 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("option remote-port has invalid port in volume %s" , this->name); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 238, GF_LOG_ERROR, "option remote-port has invalid port in volume %s" , this->name); } while (0) | |||
237 | "option remote-port has invalid port in volume %s",do { do { if (0) printf ("option remote-port has invalid port in volume %s" , this->name); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 238, GF_LOG_ERROR, "option remote-port has invalid port in volume %s" , this->name); } while (0) | |||
238 | this->name)do { do { if (0) printf ("option remote-port has invalid port in volume %s" , this->name); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 238, GF_LOG_ERROR, "option remote-port has invalid port in volume %s" , this->name); } while (0); | |||
239 | ret = -1; | |||
240 | goto err; | |||
241 | } | |||
242 | ||||
243 | /* TODO: gf_resolve is a blocking call. kick in some | |||
244 | non blocking dns techniques */ | |||
245 | ret = gf_resolve_ip6 (remote_host, remote_port, | |||
246 | sockaddr->sa_family, &this->dnscache, &addr_info); | |||
247 | if (ret == -1) { | |||
248 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("DNS resolution failed on host %s", remote_host ); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 249, GF_LOG_ERROR, "DNS resolution failed on host %s", remote_host ); } while (0) | |||
249 | "DNS resolution failed on host %s", remote_host)do { do { if (0) printf ("DNS resolution failed on host %s", remote_host ); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 249, GF_LOG_ERROR, "DNS resolution failed on host %s", remote_host ); } while (0); | |||
250 | goto err; | |||
251 | } | |||
252 | ||||
253 | memcpy (sockaddr, addr_info->ai_addr, addr_info->ai_addrlen); | |||
254 | *sockaddr_len = addr_info->ai_addrlen; | |||
255 | ||||
256 | err: | |||
257 | return ret; | |||
258 | } | |||
259 | ||||
260 | static int32_t | |||
261 | af_unix_client_get_remote_sockaddr (rpc_transport_t *this, | |||
262 | struct sockaddr *sockaddr, | |||
263 | socklen_t *sockaddr_len) | |||
264 | { | |||
265 | struct sockaddr_un *sockaddr_un = NULL((void*)0); | |||
266 | char *connect_path = NULL((void*)0); | |||
267 | data_t *connect_path_data = NULL((void*)0); | |||
268 | int32_t ret = 0; | |||
269 | ||||
270 | connect_path_data = dict_get (this->options, | |||
271 | "transport.socket.connect-path"); | |||
272 | if (!connect_path_data) { | |||
273 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("option transport.unix.connect-path not specified for " "address-family unix"); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 275, GF_LOG_ERROR, "option transport.unix.connect-path not specified for " "address-family unix"); } while (0) | |||
274 | "option transport.unix.connect-path not specified for "do { do { if (0) printf ("option transport.unix.connect-path not specified for " "address-family unix"); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 275, GF_LOG_ERROR, "option transport.unix.connect-path not specified for " "address-family unix"); } while (0) | |||
275 | "address-family unix")do { do { if (0) printf ("option transport.unix.connect-path not specified for " "address-family unix"); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 275, GF_LOG_ERROR, "option transport.unix.connect-path not specified for " "address-family unix"); } while (0); | |||
276 | ret = -1; | |||
277 | goto err; | |||
278 | } | |||
279 | ||||
280 | connect_path = data_to_str (connect_path_data); | |||
281 | if (!connect_path) { | |||
282 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("transport.unix.connect-path is null-string" ); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 283, GF_LOG_ERROR, "transport.unix.connect-path is null-string" ); } while (0) | |||
283 | "transport.unix.connect-path is null-string")do { do { if (0) printf ("transport.unix.connect-path is null-string" ); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 283, GF_LOG_ERROR, "transport.unix.connect-path is null-string" ); } while (0); | |||
284 | ret = -1; | |||
285 | goto err; | |||
286 | } | |||
287 | ||||
288 | if (strlen (connect_path) > UNIX_PATH_MAX108) { | |||
289 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("connect-path value length %""zu"" > %d octets" , strlen (connect_path), 108); } while (0); _gf_log (this-> name, "name.c", __FUNCTION__, 291, GF_LOG_ERROR, "connect-path value length %" "zu"" > %d octets", strlen (connect_path), 108); } while ( 0) | |||
290 | "connect-path value length %"GF_PRI_SIZET" > %d octets",do { do { if (0) printf ("connect-path value length %""zu"" > %d octets" , strlen (connect_path), 108); } while (0); _gf_log (this-> name, "name.c", __FUNCTION__, 291, GF_LOG_ERROR, "connect-path value length %" "zu"" > %d octets", strlen (connect_path), 108); } while ( 0) | |||
291 | strlen (connect_path), UNIX_PATH_MAX)do { do { if (0) printf ("connect-path value length %""zu"" > %d octets" , strlen (connect_path), 108); } while (0); _gf_log (this-> name, "name.c", __FUNCTION__, 291, GF_LOG_ERROR, "connect-path value length %" "zu"" > %d octets", strlen (connect_path), 108); } while ( 0); | |||
292 | ret = -1; | |||
293 | goto err; | |||
294 | } | |||
295 | ||||
296 | gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("using connect-path %s", connect_path ); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 297, GF_LOG_TRACE, "using connect-path %s", connect_path); } while (0) | |||
297 | "using connect-path %s", connect_path)do { do { if (0) printf ("using connect-path %s", connect_path ); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 297, GF_LOG_TRACE, "using connect-path %s", connect_path); } while (0); | |||
298 | sockaddr_un = (struct sockaddr_un *)sockaddr; | |||
299 | strcpy (sockaddr_un->sun_path, connect_path); | |||
300 | *sockaddr_len = sizeof (struct sockaddr_un); | |||
301 | ||||
302 | err: | |||
303 | return ret; | |||
304 | } | |||
305 | ||||
306 | static int32_t | |||
307 | af_unix_server_get_local_sockaddr (rpc_transport_t *this, | |||
308 | struct sockaddr *addr, | |||
309 | socklen_t *addr_len) | |||
310 | { | |||
311 | data_t *listen_path_data = NULL((void*)0); | |||
312 | char *listen_path = NULL((void*)0); | |||
313 | int32_t ret = 0; | |||
314 | struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr; | |||
315 | ||||
316 | ||||
317 | listen_path_data = dict_get (this->options, | |||
318 | "transport.socket.listen-path"); | |||
319 | if (!listen_path_data) { | |||
320 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("missing option transport.socket.listen-path" ); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 321, GF_LOG_ERROR, "missing option transport.socket.listen-path" ); } while (0) | |||
321 | "missing option transport.socket.listen-path")do { do { if (0) printf ("missing option transport.socket.listen-path" ); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 321, GF_LOG_ERROR, "missing option transport.socket.listen-path" ); } while (0); | |||
322 | ret = -1; | |||
323 | goto err; | |||
324 | } | |||
325 | ||||
326 | listen_path = data_to_str (listen_path_data); | |||
327 | ||||
328 | #ifndef UNIX_PATH_MAX108 | |||
329 | #define UNIX_PATH_MAX108 108 | |||
330 | #endif | |||
331 | ||||
332 | if (strlen (listen_path) > UNIX_PATH_MAX108) { | |||
333 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("option transport.unix.listen-path has value length " "%""zu"" > %d", strlen (listen_path), 108); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 336, GF_LOG_ERROR, "option transport.unix.listen-path has value length " "%""zu"" > %d", strlen (listen_path), 108); } while (0) | |||
334 | "option transport.unix.listen-path has value length "do { do { if (0) printf ("option transport.unix.listen-path has value length " "%""zu"" > %d", strlen (listen_path), 108); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 336, GF_LOG_ERROR, "option transport.unix.listen-path has value length " "%""zu"" > %d", strlen (listen_path), 108); } while (0) | |||
335 | "%"GF_PRI_SIZET" > %d",do { do { if (0) printf ("option transport.unix.listen-path has value length " "%""zu"" > %d", strlen (listen_path), 108); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 336, GF_LOG_ERROR, "option transport.unix.listen-path has value length " "%""zu"" > %d", strlen (listen_path), 108); } while (0) | |||
336 | strlen (listen_path), UNIX_PATH_MAX)do { do { if (0) printf ("option transport.unix.listen-path has value length " "%""zu"" > %d", strlen (listen_path), 108); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 336, GF_LOG_ERROR, "option transport.unix.listen-path has value length " "%""zu"" > %d", strlen (listen_path), 108); } while (0); | |||
337 | ret = -1; | |||
338 | goto err; | |||
339 | } | |||
340 | ||||
341 | sunaddr->sun_family = AF_UNIX1; | |||
342 | strcpy (sunaddr->sun_path, listen_path); | |||
343 | *addr_len = sizeof (struct sockaddr_un); | |||
344 | ||||
345 | err: | |||
346 | return ret; | |||
347 | } | |||
348 | ||||
349 | static int32_t | |||
350 | af_inet_server_get_local_sockaddr (rpc_transport_t *this, | |||
351 | struct sockaddr *addr, | |||
352 | socklen_t *addr_len) | |||
353 | { | |||
354 | struct addrinfo hints, *res = 0, *rp = NULL((void*)0); | |||
355 | data_t *listen_port_data = NULL((void*)0), *listen_host_data = NULL((void*)0); | |||
356 | uint16_t listen_port = -1; | |||
357 | char service[NI_MAXSERV32], *listen_host = NULL((void*)0); | |||
358 | dict_t *options = NULL((void*)0); | |||
359 | int32_t ret = 0; | |||
360 | ||||
361 | options = this->options; | |||
362 | ||||
363 | listen_port_data = dict_get (options, "transport.socket.listen-port"); | |||
364 | listen_host_data = dict_get (options, "transport.socket.bind-address"); | |||
365 | ||||
366 | if (listen_port_data) | |||
367 | { | |||
368 | listen_port = data_to_uint16 (listen_port_data); | |||
369 | } | |||
370 | ||||
371 | if (listen_port == (uint16_t) -1) | |||
372 | listen_port = GF_DEFAULT_SOCKET_LISTEN_PORT24007; | |||
373 | ||||
374 | ||||
375 | if (listen_host_data) | |||
376 | { | |||
377 | listen_host = data_to_str (listen_host_data); | |||
378 | } else { | |||
379 | if (addr->sa_family == AF_INET610) { | |||
380 | struct sockaddr_in6 *in = (struct sockaddr_in6 *) addr; | |||
381 | in->sin6_addr = in6addr_any; | |||
382 | in->sin6_port = htons(listen_port); | |||
383 | *addr_len = sizeof(struct sockaddr_in6); | |||
384 | goto out; | |||
385 | } else if (addr->sa_family == AF_INET2) { | |||
386 | struct sockaddr_in *in = (struct sockaddr_in *) addr; | |||
387 | in->sin_addr.s_addr = htonl(INADDR_ANY((in_addr_t) 0x00000000)); | |||
388 | in->sin_port = htons(listen_port); | |||
389 | *addr_len = sizeof(struct sockaddr_in); | |||
390 | goto out; | |||
391 | } | |||
392 | } | |||
393 | ||||
394 | memset (service, 0, sizeof (service)); | |||
395 | sprintf (service, "%d", listen_port); | |||
396 | ||||
397 | memset (&hints, 0, sizeof (hints)); | |||
398 | hints.ai_family = addr->sa_family; | |||
399 | hints.ai_socktype = SOCK_STREAMSOCK_STREAM; | |||
400 | hints.ai_flags = AI_PASSIVE0x0001 | AI_ADDRCONFIG0x0020; | |||
401 | ||||
402 | ret = getaddrinfo(listen_host, service, &hints, &res); | |||
403 | if (ret != 0) { | |||
404 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("getaddrinfo failed for host %s, service %s (%s)" , listen_host, service, gai_strerror (ret)); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 406, GF_LOG_ERROR, "getaddrinfo failed for host %s, service %s (%s)" , listen_host, service, gai_strerror (ret)); } while (0) | |||
405 | "getaddrinfo failed for host %s, service %s (%s)",do { do { if (0) printf ("getaddrinfo failed for host %s, service %s (%s)" , listen_host, service, gai_strerror (ret)); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 406, GF_LOG_ERROR, "getaddrinfo failed for host %s, service %s (%s)" , listen_host, service, gai_strerror (ret)); } while (0) | |||
406 | listen_host, service, gai_strerror (ret))do { do { if (0) printf ("getaddrinfo failed for host %s, service %s (%s)" , listen_host, service, gai_strerror (ret)); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 406, GF_LOG_ERROR, "getaddrinfo failed for host %s, service %s (%s)" , listen_host, service, gai_strerror (ret)); } while (0); | |||
407 | ret = -1; | |||
408 | goto out; | |||
409 | } | |||
410 | /* IPV6 server can handle both ipv4 and ipv6 clients */ | |||
411 | for (rp = res; rp != NULL((void*)0); rp = rp->ai_next) { | |||
412 | if (rp->ai_addr == NULL((void*)0)) | |||
413 | continue; | |||
414 | if (rp->ai_family == AF_INET610) { | |||
415 | memcpy (addr, rp->ai_addr, rp->ai_addrlen); | |||
416 | *addr_len = rp->ai_addrlen; | |||
417 | } | |||
418 | } | |||
419 | ||||
420 | if (!(*addr_len)) { | |||
421 | memcpy (addr, res->ai_addr, res->ai_addrlen); | |||
| ||||
422 | *addr_len = res->ai_addrlen; | |||
423 | } | |||
424 | ||||
425 | freeaddrinfo (res); | |||
426 | ||||
427 | out: | |||
428 | return ret; | |||
429 | } | |||
430 | ||||
431 | int32_t | |||
432 | client_bind (rpc_transport_t *this, | |||
433 | struct sockaddr *sockaddr, | |||
434 | socklen_t *sockaddr_len, | |||
435 | int sock) | |||
436 | { | |||
437 | int ret = 0; | |||
438 | ||||
439 | *sockaddr_len = sizeof (struct sockaddr_in6); | |||
440 | switch (sockaddr->sa_family) | |||
441 | { | |||
442 | case AF_INET_SDP27: | |||
443 | case AF_INET2: | |||
444 | *sockaddr_len = sizeof (struct sockaddr_in); | |||
445 | ||||
446 | case AF_INET610: | |||
447 | if (!this->bind_insecure) { | |||
448 | ret = af_inet_bind_to_port_lt_ceiling (sock, sockaddr, | |||
449 | *sockaddr_len, GF_CLIENT_PORT_CEILING1024); | |||
450 | } | |||
451 | if (ret == -1) { | |||
452 | gf_log (this->name, GF_LOG_DEBUG,do { do { if (0) printf ("cannot bind inet socket (%d) to port less than %d (%s)" , sock, 1024, strerror ((*__errno_location ()))); } while (0) ; _gf_log (this->name, "name.c", __FUNCTION__, 454, GF_LOG_DEBUG , "cannot bind inet socket (%d) to port less than %d (%s)", sock , 1024, strerror ((*__errno_location ()))); } while (0) | |||
453 | "cannot bind inet socket (%d) to port less than %d (%s)",do { do { if (0) printf ("cannot bind inet socket (%d) to port less than %d (%s)" , sock, 1024, strerror ((*__errno_location ()))); } while (0) ; _gf_log (this->name, "name.c", __FUNCTION__, 454, GF_LOG_DEBUG , "cannot bind inet socket (%d) to port less than %d (%s)", sock , 1024, strerror ((*__errno_location ()))); } while (0) | |||
454 | sock, GF_CLIENT_PORT_CEILING, strerror (errno))do { do { if (0) printf ("cannot bind inet socket (%d) to port less than %d (%s)" , sock, 1024, strerror ((*__errno_location ()))); } while (0) ; _gf_log (this->name, "name.c", __FUNCTION__, 454, GF_LOG_DEBUG , "cannot bind inet socket (%d) to port less than %d (%s)", sock , 1024, strerror ((*__errno_location ()))); } while (0); | |||
455 | ret = 0; | |||
456 | } | |||
457 | break; | |||
458 | ||||
459 | case AF_UNIX1: | |||
460 | *sockaddr_len = sizeof (struct sockaddr_un); | |||
461 | ret = af_unix_client_bind (this, (struct sockaddr *)sockaddr, | |||
462 | *sockaddr_len, sock); | |||
463 | break; | |||
464 | ||||
465 | default: | |||
466 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("unknown address family %d", sockaddr ->sa_family); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 467, GF_LOG_ERROR, "unknown address family %d" , sockaddr->sa_family); } while (0) | |||
467 | "unknown address family %d", sockaddr->sa_family)do { do { if (0) printf ("unknown address family %d", sockaddr ->sa_family); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 467, GF_LOG_ERROR, "unknown address family %d" , sockaddr->sa_family); } while (0); | |||
468 | ret = -1; | |||
469 | break; | |||
470 | } | |||
471 | ||||
472 | return ret; | |||
473 | } | |||
474 | ||||
475 | int32_t | |||
476 | socket_client_get_remote_sockaddr (rpc_transport_t *this, | |||
477 | struct sockaddr *sockaddr, | |||
478 | socklen_t *sockaddr_len, | |||
479 | sa_family_t *sa_family) | |||
480 | { | |||
481 | int32_t ret = 0; | |||
482 | ||||
483 | GF_VALIDATE_OR_GOTO ("socket", sockaddr, err)do { if (!sockaddr) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "sockaddr"); } while (0); _gf_log_callingfn ("socket", "name.c", __FUNCTION__, 483, GF_LOG_ERROR, "invalid argument: " "sockaddr"); } while (0); goto err; } } while (0); | |||
484 | GF_VALIDATE_OR_GOTO ("socket", sockaddr_len, err)do { if (!sockaddr_len) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "sockaddr_len"); } while (0); _gf_log_callingfn ("socket", "name.c", __FUNCTION__, 484 , GF_LOG_ERROR, "invalid argument: " "sockaddr_len"); } while (0); goto err; } } while (0); | |||
485 | GF_VALIDATE_OR_GOTO ("socket", sa_family, err)do { if (!sa_family) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "sa_family"); } while (0 ); _gf_log_callingfn ("socket", "name.c", __FUNCTION__, 485, GF_LOG_ERROR , "invalid argument: " "sa_family"); } while (0); goto err; } } while (0); | |||
486 | ||||
487 | ret = client_fill_address_family (this, &sockaddr->sa_family); | |||
488 | if (ret) { | |||
489 | ret = -1; | |||
490 | goto err; | |||
491 | } | |||
492 | ||||
493 | *sa_family = sockaddr->sa_family; | |||
494 | ||||
495 | switch (sockaddr->sa_family) | |||
496 | { | |||
497 | case AF_INET_SDP27: | |||
498 | sockaddr->sa_family = AF_INET2; | |||
499 | ||||
500 | case AF_INET2: | |||
501 | case AF_INET610: | |||
502 | case AF_UNSPEC0: | |||
503 | ret = af_inet_client_get_remote_sockaddr (this, sockaddr, | |||
504 | sockaddr_len); | |||
505 | break; | |||
506 | ||||
507 | case AF_UNIX1: | |||
508 | ret = af_unix_client_get_remote_sockaddr (this, sockaddr, | |||
509 | sockaddr_len); | |||
510 | break; | |||
511 | ||||
512 | default: | |||
513 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("unknown address-family %d", sockaddr ->sa_family); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 514, GF_LOG_ERROR, "unknown address-family %d" , sockaddr->sa_family); } while (0) | |||
514 | "unknown address-family %d", sockaddr->sa_family)do { do { if (0) printf ("unknown address-family %d", sockaddr ->sa_family); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 514, GF_LOG_ERROR, "unknown address-family %d" , sockaddr->sa_family); } while (0); | |||
515 | ret = -1; | |||
516 | } | |||
517 | ||||
518 | if (*sa_family == AF_UNSPEC0) { | |||
519 | *sa_family = sockaddr->sa_family; | |||
520 | } | |||
521 | ||||
522 | err: | |||
523 | return ret; | |||
524 | } | |||
525 | ||||
526 | ||||
527 | int32_t | |||
528 | server_fill_address_family (rpc_transport_t *this, sa_family_t *sa_family) | |||
529 | { | |||
530 | data_t *address_family_data = NULL((void*)0); | |||
531 | int32_t ret = -1; | |||
532 | ||||
533 | GF_VALIDATE_OR_GOTO ("socket", sa_family, out)do { if (!sa_family) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "sa_family"); } while (0 ); _gf_log_callingfn ("socket", "name.c", __FUNCTION__, 533, GF_LOG_ERROR , "invalid argument: " "sa_family"); } while (0); goto out; } } while (0); | |||
534 | ||||
535 | address_family_data = dict_get (this->options, | |||
536 | "transport.address-family"); | |||
537 | if (address_family_data) { | |||
538 | char *address_family = NULL((void*)0); | |||
539 | address_family = data_to_str (address_family_data); | |||
540 | ||||
541 | if (!strcasecmp (address_family, "inet")) { | |||
542 | *sa_family = AF_INET2; | |||
543 | } else if (!strcasecmp (address_family, "inet6")) { | |||
544 | *sa_family = AF_INET610; | |||
545 | } else if (!strcasecmp (address_family, "inet-sdp")) { | |||
546 | *sa_family = AF_INET_SDP27; | |||
547 | } else if (!strcasecmp (address_family, "unix")) { | |||
548 | *sa_family = AF_UNIX1; | |||
549 | } else { | |||
550 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("unknown address family (%s) specified" , address_family); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 551, GF_LOG_ERROR, "unknown address family (%s) specified" , address_family); } while (0) | |||
551 | "unknown address family (%s) specified", address_family)do { do { if (0) printf ("unknown address family (%s) specified" , address_family); } while (0); _gf_log (this->name, "name.c" , __FUNCTION__, 551, GF_LOG_ERROR, "unknown address family (%s) specified" , address_family); } while (0); | |||
552 | *sa_family = AF_UNSPEC0; | |||
553 | goto out; | |||
554 | } | |||
555 | } else { | |||
556 | gf_log (this->name, GF_LOG_DEBUG,do { do { if (0) printf ("option address-family not specified, defaulting to inet" ); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 557, GF_LOG_DEBUG, "option address-family not specified, defaulting to inet" ); } while (0) | |||
557 | "option address-family not specified, defaulting to inet")do { do { if (0) printf ("option address-family not specified, defaulting to inet" ); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 557, GF_LOG_DEBUG, "option address-family not specified, defaulting to inet" ); } while (0); | |||
558 | *sa_family = AF_INET2; | |||
559 | } | |||
560 | ||||
561 | ret = 0; | |||
562 | out: | |||
563 | return ret; | |||
564 | } | |||
565 | ||||
566 | ||||
567 | int32_t | |||
568 | socket_server_get_local_sockaddr (rpc_transport_t *this, struct sockaddr *addr, | |||
569 | socklen_t *addr_len, sa_family_t *sa_family) | |||
570 | { | |||
571 | int32_t ret = -1; | |||
572 | ||||
573 | GF_VALIDATE_OR_GOTO ("socket", sa_family, err)do { if (!sa_family) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "sa_family"); } while (0 ); _gf_log_callingfn ("socket", "name.c", __FUNCTION__, 573, GF_LOG_ERROR , "invalid argument: " "sa_family"); } while (0); goto err; } } while (0); | |||
574 | GF_VALIDATE_OR_GOTO ("socket", addr, err)do { if (!addr) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "addr"); } while (0); _gf_log_callingfn ("socket", "name.c", __FUNCTION__, 574, GF_LOG_ERROR, "invalid argument: " "addr"); } while (0); goto err; } } while (0); | |||
575 | GF_VALIDATE_OR_GOTO ("socket", addr_len, err)do { if (!addr_len) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "addr_len"); } while (0); _gf_log_callingfn ("socket", "name.c", __FUNCTION__, 575, GF_LOG_ERROR, "invalid argument: " "addr_len"); } while (0); goto err; } } while (0); | |||
576 | ||||
577 | ret = server_fill_address_family (this, &addr->sa_family); | |||
578 | if (ret == -1) { | |||
| ||||
579 | goto err; | |||
580 | } | |||
581 | ||||
582 | *sa_family = addr->sa_family; | |||
583 | ||||
584 | switch (addr->sa_family) | |||
585 | { | |||
586 | case AF_INET_SDP27: | |||
587 | addr->sa_family = AF_INET2; | |||
588 | ||||
589 | case AF_INET2: | |||
590 | case AF_INET610: | |||
591 | case AF_UNSPEC0: | |||
592 | ret = af_inet_server_get_local_sockaddr (this, addr, addr_len); | |||
593 | break; | |||
594 | ||||
595 | case AF_UNIX1: | |||
596 | ret = af_unix_server_get_local_sockaddr (this, addr, addr_len); | |||
597 | break; | |||
598 | } | |||
599 | ||||
600 | if (*sa_family == AF_UNSPEC0) { | |||
601 | *sa_family = addr->sa_family; | |||
602 | } | |||
603 | ||||
604 | err: | |||
605 | return ret; | |||
606 | } | |||
607 | ||||
608 | int32_t | |||
609 | fill_inet6_inet_identifiers (rpc_transport_t *this, struct sockaddr_storage *addr, | |||
610 | int32_t addr_len, char *identifier) | |||
611 | { | |||
612 | union gf_sock_union sock_union; | |||
613 | ||||
614 | char service[NI_MAXSERV32] = {0,}; | |||
615 | char host[NI_MAXHOST1025] = {0,}; | |||
616 | int32_t ret = 0; | |||
617 | int32_t tmpaddr_len = 0; | |||
618 | int32_t one_to_four = 0; | |||
619 | int32_t four_to_eight = 0; | |||
620 | int32_t twelve_to_sixteen = 0; | |||
621 | int16_t eight_to_ten = 0; | |||
622 | int16_t ten_to_twelve = 0; | |||
623 | ||||
624 | memset (&sock_union, 0, sizeof (sock_union)); | |||
625 | sock_union.storage = *addr; | |||
626 | tmpaddr_len = addr_len; | |||
627 | ||||
628 | if (sock_union.sa.sa_family == AF_INET610) { | |||
629 | one_to_four = sock_union.sin6.sin6_addr.s6_addr32__in6_u.__u6_addr32[0]; | |||
630 | four_to_eight = sock_union.sin6.sin6_addr.s6_addr32__in6_u.__u6_addr32[1]; | |||
631 | #ifdef GF_SOLARIS_HOST_OS | |||
632 | eight_to_ten = S6_ADDR16(sock_union.sin6.sin6_addr)[4]; | |||
633 | #else | |||
634 | eight_to_ten = sock_union.sin6.sin6_addr.s6_addr16__in6_u.__u6_addr16[4]; | |||
635 | #endif | |||
636 | ||||
637 | #ifdef GF_SOLARIS_HOST_OS | |||
638 | ten_to_twelve = S6_ADDR16(sock_union.sin6.sin6_addr)[5]; | |||
639 | #else | |||
640 | ten_to_twelve = sock_union.sin6.sin6_addr.s6_addr16__in6_u.__u6_addr16[5]; | |||
641 | #endif | |||
642 | ||||
643 | twelve_to_sixteen = sock_union.sin6.sin6_addr.s6_addr32__in6_u.__u6_addr32[3]; | |||
644 | ||||
645 | /* ipv4 mapped ipv6 address has | |||
646 | bits 0-80: 0 | |||
647 | bits 80-96: 0xffff | |||
648 | bits 96-128: ipv4 address | |||
649 | */ | |||
650 | ||||
651 | if (one_to_four == 0 && | |||
652 | four_to_eight == 0 && | |||
653 | eight_to_ten == 0 && | |||
654 | ten_to_twelve == -1) { | |||
655 | struct sockaddr_in *in_ptr = &sock_union.sin; | |||
656 | memset (&sock_union, 0, sizeof (sock_union)); | |||
657 | ||||
658 | in_ptr->sin_family = AF_INET2; | |||
659 | in_ptr->sin_port = ((struct sockaddr_in6 *)addr)->sin6_port; | |||
660 | in_ptr->sin_addr.s_addr = twelve_to_sixteen; | |||
661 | tmpaddr_len = sizeof (*in_ptr); | |||
662 | } | |||
663 | } | |||
664 | ||||
665 | ret = getnameinfo (&sock_union.sa, | |||
666 | tmpaddr_len, | |||
667 | host, sizeof (host), | |||
668 | service, sizeof (service), | |||
669 | NI_NUMERICHOST1 | NI_NUMERICSERV2); | |||
670 | if (ret != 0) { | |||
671 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("getnameinfo failed (%s)", gai_strerror (ret)); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 672, GF_LOG_ERROR, "getnameinfo failed (%s)", gai_strerror ( ret)); } while (0) | |||
672 | "getnameinfo failed (%s)", gai_strerror (ret))do { do { if (0) printf ("getnameinfo failed (%s)", gai_strerror (ret)); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 672, GF_LOG_ERROR, "getnameinfo failed (%s)", gai_strerror ( ret)); } while (0); | |||
673 | } | |||
674 | ||||
675 | sprintf (identifier, "%s:%s", host, service); | |||
676 | ||||
677 | return ret; | |||
678 | } | |||
679 | ||||
680 | int32_t | |||
681 | get_transport_identifiers (rpc_transport_t *this) | |||
682 | { | |||
683 | int32_t ret = 0; | |||
684 | char is_inet_sdp = 0; | |||
685 | ||||
686 | switch (((struct sockaddr *) &this->myinfo.sockaddr)->sa_family) | |||
687 | { | |||
688 | case AF_INET_SDP27: | |||
689 | is_inet_sdp = 1; | |||
690 | ((struct sockaddr *) &this->peerinfo.sockaddr)->sa_family = ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family = AF_INET2; | |||
691 | ||||
692 | case AF_INET2: | |||
693 | case AF_INET610: | |||
694 | { | |||
695 | ret = fill_inet6_inet_identifiers (this, | |||
696 | &this->myinfo.sockaddr, | |||
697 | this->myinfo.sockaddr_len, | |||
698 | this->myinfo.identifier); | |||
699 | if (ret == -1) { | |||
700 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("cannot fill inet/inet6 identifier for server" ); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 701, GF_LOG_ERROR, "cannot fill inet/inet6 identifier for server" ); } while (0) | |||
701 | "cannot fill inet/inet6 identifier for server")do { do { if (0) printf ("cannot fill inet/inet6 identifier for server" ); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 701, GF_LOG_ERROR, "cannot fill inet/inet6 identifier for server" ); } while (0); | |||
702 | goto err; | |||
703 | } | |||
704 | ||||
705 | ret = fill_inet6_inet_identifiers (this, | |||
706 | &this->peerinfo.sockaddr, | |||
707 | this->peerinfo.sockaddr_len, | |||
708 | this->peerinfo.identifier); | |||
709 | if (ret == -1) { | |||
710 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("cannot fill inet/inet6 identifier for client" ); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 711, GF_LOG_ERROR, "cannot fill inet/inet6 identifier for client" ); } while (0) | |||
711 | "cannot fill inet/inet6 identifier for client")do { do { if (0) printf ("cannot fill inet/inet6 identifier for client" ); } while (0); _gf_log (this->name, "name.c", __FUNCTION__ , 711, GF_LOG_ERROR, "cannot fill inet/inet6 identifier for client" ); } while (0); | |||
712 | goto err; | |||
713 | } | |||
714 | ||||
715 | if (is_inet_sdp) { | |||
716 | ((struct sockaddr *) &this->peerinfo.sockaddr)->sa_family = ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family = AF_INET_SDP27; | |||
717 | } | |||
718 | } | |||
719 | break; | |||
720 | ||||
721 | case AF_UNIX1: | |||
722 | { | |||
723 | struct sockaddr_un *sunaddr = NULL((void*)0); | |||
724 | ||||
725 | sunaddr = (struct sockaddr_un *) &this->myinfo.sockaddr; | |||
726 | strcpy (this->myinfo.identifier, sunaddr->sun_path); | |||
727 | ||||
728 | sunaddr = (struct sockaddr_un *) &this->peerinfo.sockaddr; | |||
729 | strcpy (this->peerinfo.identifier, sunaddr->sun_path); | |||
730 | } | |||
731 | break; | |||
732 | ||||
733 | default: | |||
734 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("unknown address family (%d)", ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 736 , GF_LOG_ERROR, "unknown address family (%d)", ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family); } while (0 ) | |||
735 | "unknown address family (%d)",do { do { if (0) printf ("unknown address family (%d)", ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 736 , GF_LOG_ERROR, "unknown address family (%d)", ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family); } while (0 ) | |||
736 | ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family)do { do { if (0) printf ("unknown address family (%d)", ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family); } while (0); _gf_log (this->name, "name.c", __FUNCTION__, 736 , GF_LOG_ERROR, "unknown address family (%d)", ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family); } while (0 ); | |||
737 | ret = -1; | |||
738 | break; | |||
739 | } | |||
740 | ||||
741 | err: | |||
742 | return ret; | |||
743 | } |