2
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2
Copyright (C) 2007-2008 MySQL AB, 2008 Sun Microsystems, Inc
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License as
6
published by the Free Software Foundation; version 2 of the
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; version 2 of the License.
9
8
This program is distributed in the hope that it will be useful,
10
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
11
GNU General Public License for more details.
14
13
You should have received a copy of the GNU General Public License
15
14
along with this program; if not, write to the Free Software
16
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
15
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
20
#ifdef HAVE_CONFIG_H
21
21
#include "config.h"
67
65
void network_address_free(network_address *addr) {
73
* if the name we're freeing starts with a '/', we're
74
* looking at a unix socket which needs to be removed
76
if (addr->can_unlink_socket == TRUE && addr->name != NULL &&
77
addr->name->str != NULL) {
81
name = addr->name->str;
85
g_debug("%s: removing socket %s successful",
88
if (errno != EPERM && errno != EACCES) {
89
g_critical("%s: removing socket %s failed: %s (%d)",
90
G_STRLOC, name, strerror(errno), errno);
97
68
g_string_free(addr->name, TRUE);
105
77
static gint network_address_set_address_ip(network_address *addr, const gchar *address, guint port) {
106
g_return_val_if_fail(addr, -1);
108
82
if (port > 65535) {
109
g_critical("%s: illegal value %u for port, only 1 ... 65535 allowed",
114
86
memset(&addr->addr.ipv4, 0, sizeof(struct sockaddr_in));
116
if (NULL == address ||
117
strlen(address) == 0 ||
88
if (strlen(address) == 0 ||
118
89
0 == strcmp("0.0.0.0", address)) {
120
91
addr->addr.ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
121
addr->addr.ipv4.sin_family = AF_INET; /* "default" family */
123
#ifdef HAVE_GETADDRINFO
124
struct addrinfo *ai = NULL, hint;
127
memset(&hint, 0, sizeof (hint));
129
* FIXME: when we add support for IPv6, we'll have to do one
130
* PF_INET* after the other
132
hint.ai_family = PF_INET;
133
if ((rc = getaddrinfo(address, NULL, &hint, &ai)) != 0) {
134
g_critical("getaddrinfo(%s) failed with %s", address,
140
family = ai->ai_family;
141
#if 0 /* keep this for when we do IPv6 */
142
if (family == PF_INET6) {
143
memcpy(&addr->addr.ipv6,
144
(struct sockaddr_in6 *) ai->ai_addr,
145
sizeof (addr->addr.ipv6));
149
if (family == PF_INET) {
150
memcpy(&addr->addr.ipv4,
151
(struct sockaddr_in *) ai->ai_addr,
152
sizeof (addr->addr.ipv4));
156
} while (NULL != ai);
159
/* the family we print here is the *last* ai's */
160
g_critical("address %s doesn't resolve to a valid/supported "
161
"address family: %d expected, last found %d", address,
170
static GStaticMutex gh_mutex = G_STATIC_MUTEX_INIT;
172
g_static_mutex_lock(&gh_mutex);
174
95
he = gethostbyname(address);
176
g_static_mutex_unlock(&gh_mutex);
181
102
g_assert(he->h_length == sizeof(struct in_addr));
183
104
memcpy(&(addr->addr.ipv4.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
184
g_static_mutex_unlock(&gh_mutex);
185
addr->addr.ipv4.sin_family = AF_INET;
186
#endif /* HAVE_GETADDRINFO */
107
addr->addr.ipv4.sin_family = AF_INET;
189
108
addr->addr.ipv4.sin_port = htons(port);
190
109
addr->len = sizeof(struct sockaddr_in);
192
(void) network_address_refresh_name(addr);
111
network_address_refresh_name(addr);
197
static gint network_address_set_address_un(network_address *addr, const gchar *address) {
198
g_return_val_if_fail(addr, -1);
199
g_return_val_if_fail(address, -1);
116
gboolean network_address_set_address_un(network_address *addr, gchar *address) {
201
117
#ifdef HAVE_SYS_UN_H
202
118
if (strlen(address) >= sizeof(addr->addr.un.sun_path) - 1) {
203
119
g_critical("unix-path is too long: %s", address);
228
144
* @param address the address string
229
145
* @return 0 on success, -1 otherwise
231
gint network_address_set_address(network_address *addr, const gchar *address) {
147
gint network_address_set_address(network_address *addr, gchar *address) {
234
150
g_return_val_if_fail(addr, -1);
236
152
/* split the address:port */
237
if (address[0] == '/')
153
if (address[0] == '/') {
238
154
return network_address_set_address_un(addr, address);
240
if (NULL != (s = strchr(address, ':'))) {
242
char *ip_address = g_strndup(address, s - address); /* may be NULL for strdup(..., 0) */
243
char *port_err = NULL;
245
guint port = strtoul(s + 1, &port_err, 10);
247
if (*(s + 1) == '\0') {
248
g_critical("%s: IP-address has to be in the form [<ip>][:<port>], is '%s'. No port number",
251
} else if (*port_err != '\0') {
252
g_critical("%s: IP-address has to be in the form [<ip>][:<port>], is '%s'. Failed to parse the port at '%s'",
253
G_STRLOC, address, port_err);
256
ret = network_address_set_address_ip(addr, ip_address, port);
259
if (ip_address) g_free(ip_address);
155
} else if (NULL != (s = strchr(address, ':'))) {
157
char *ip_address = g_strndup(address, s - address);
159
guint port = strtoul(s + 1, NULL, 10);
161
ret = network_address_set_address_ip(addr, ip_address, port);
166
} else { /* perhaps it is a plain IP address, lets add the default-port */
167
return network_address_set_address_ip(addr, address, 3306);
263
/* perhaps it is a plain IP address, lets add the default-port */
264
return network_address_set_address_ip(addr, address, 3306);
170
g_assert_not_reached();
299
205
gboolean network_address_is_local(network_address *dst_addr, network_address *src_addr) {
300
206
if (src_addr->addr.common.sa_family != dst_addr->addr.common.sa_family) {
302
if (src_addr->addr.common.sa_family == AF_UNIX ||
303
dst_addr->addr.common.sa_family == AF_UNIX) {
304
/* AF_UNIX is always local,
305
* even if one of the two sides doesn't return a reasonable protocol
312
207
g_message("%s: is-local family %d != %d",
314
209
src_addr->addr.common.sa_family,