~jan-kneschke/mysql-proxy/packet-tracking-assertions

« back to all changes in this revision

Viewing changes to src/network-address.c

  • Committer: Kay Roepke
  • Date: 2009-09-02 14:04:24 UTC
  • Revision ID: kay@sun.com-20090902140424-j795532tpi1y06lt
Fix linking errors on Win32:
 * chassis-timing was missing CHASSIS_API
 * evutil_socketpair was not exported

Suppress superfluous warnings from MSVC and fix a couple of valid ones (unused variables etc).

Add third path to the dllexport macros, to be used in testcases which are statically linked (fixes linker warnings).
Fixes PR-237

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* $%BEGINLICENSE%$
2
 
 Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
 
2
 Copyright (C) 2007-2008 MySQL AB, 2008 Sun Microsystems, Inc
3
3
 
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
7
 
 License.
 
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.
8
7
 
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.
13
12
 
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
17
 
 02110-1301  USA
 
15
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
16
 
19
17
 $%ENDLICENSE%$ */
 
18
 
 
19
 
20
20
#ifdef HAVE_CONFIG_H
21
21
#include "config.h"
22
22
#endif
45
45
#include <string.h>
46
46
#include <errno.h>
47
47
#include <fcntl.h>
48
 
#include <glib.h>
49
 
#include <glib/gstdio.h>
50
48
 
51
49
#include "network-address.h"
52
50
#include "glib-ext.h"
65
63
}
66
64
 
67
65
void network_address_free(network_address *addr) {
68
 
 
69
66
        if (!addr) return;
70
67
 
71
 
#ifndef WIN32
72
 
        /*
73
 
         * if the name we're freeing starts with a '/', we're
74
 
         * looking at a unix socket which needs to be removed
75
 
         */
76
 
        if (addr->can_unlink_socket == TRUE && addr->name != NULL &&
77
 
                        addr->name->str != NULL) {
78
 
                gchar   *name;
79
 
                int             ret;
80
 
 
81
 
                name = addr->name->str;
82
 
                if (name[0] == '/') {
83
 
                        ret = g_remove(name);
84
 
                        if (ret == 0) {
85
 
                                g_debug("%s: removing socket %s successful", 
86
 
                                        G_STRLOC, name);
87
 
                        } else {
88
 
                                if (errno != EPERM && errno != EACCES) {
89
 
                                        g_critical("%s: removing socket %s failed: %s (%d)", 
90
 
                                                G_STRLOC, name, strerror(errno), errno);
91
 
                                }
92
 
                        }
93
 
                }
94
 
        }
95
 
#endif /* WIN32 */
96
 
 
97
68
        g_string_free(addr->name, TRUE);
 
69
 
98
70
        g_free(addr);
99
71
}
100
72
 
103
75
}
104
76
 
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);
 
78
        if (port == 0) {
 
79
                return -1;
 
80
        }
107
81
 
108
82
        if (port > 65535) {
109
 
                g_critical("%s: illegal value %u for port, only 1 ... 65535 allowed",
110
 
                                G_STRLOC, port);
111
83
                return -1;
112
84
        }
113
85
 
114
86
        memset(&addr->addr.ipv4, 0, sizeof(struct sockaddr_in));
115
87
 
116
 
        if (NULL == address ||
117
 
            strlen(address) == 0 || 
 
88
        if (strlen(address) == 0 || 
118
89
            0 == strcmp("0.0.0.0", address)) {
119
90
                /* no ip */
120
91
                addr->addr.ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
121
 
                addr->addr.ipv4.sin_family = AF_INET; /* "default" family */
122
92
        } else {
123
 
#ifdef HAVE_GETADDRINFO
124
 
                struct addrinfo *ai = NULL, hint;
125
 
                int                             rc, family;
126
 
                
127
 
                memset(&hint, 0, sizeof (hint));
128
 
                /*
129
 
                 * FIXME: when we add support for IPv6, we'll have to do one
130
 
                 * PF_INET* after the other
131
 
                 */
132
 
                hint.ai_family = PF_INET;
133
 
                if ((rc = getaddrinfo(address, NULL, &hint, &ai)) != 0) {
134
 
                        g_critical("getaddrinfo(%s) failed with %s", address, 
135
 
                                           gai_strerror(rc));
136
 
                        return -1;
137
 
                }
138
 
 
139
 
                do {
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));
146
 
                                break;
147
 
                        } 
148
 
#endif /* 0 */
149
 
                        if (family == PF_INET) {
150
 
                                memcpy(&addr->addr.ipv4,
151
 
                                                (struct sockaddr_in *) ai->ai_addr, 
152
 
                                                sizeof (addr->addr.ipv4));
153
 
                                break;
154
 
                        }
155
 
                        ai = ai->ai_next;
156
 
                } while (NULL != ai);
157
 
 
158
 
                if (ai == NULL) {
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,
162
 
                                           PF_INET, family);
163
 
                        freeaddrinfo(ai);
164
 
                        return -1;
165
 
                }
166
 
 
167
 
                freeaddrinfo(ai);
168
 
#else 
169
 
                struct hostent  *he;
170
 
                static GStaticMutex gh_mutex = G_STATIC_MUTEX_INIT;
171
 
 
172
 
                g_static_mutex_lock(&gh_mutex);
 
93
                struct hostent *he;
173
94
 
174
95
                he = gethostbyname(address);
175
 
                if (NULL == he) {
176
 
                        g_static_mutex_unlock(&gh_mutex);
 
96
 
 
97
                if (NULL == he)  {
177
98
                        return -1;
178
99
                }
179
100
 
181
102
                g_assert(he->h_length == sizeof(struct in_addr));
182
103
 
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 */
187
105
        }
188
106
 
 
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);
191
110
 
192
 
        (void) network_address_refresh_name(addr);
 
111
        network_address_refresh_name(addr);
193
112
 
194
113
        return 0;
195
114
}
196
115
 
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);
200
 
 
 
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
230
146
 */
231
 
gint network_address_set_address(network_address *addr, const gchar *address) {
 
147
gint network_address_set_address(network_address *addr, gchar *address) {
232
148
        gchar *s;
233
149
 
234
150
        g_return_val_if_fail(addr, -1);
235
151
 
236
152
        /* split the address:port */
237
 
        if (address[0] == '/')
 
153
        if (address[0] == '/') {
238
154
                return network_address_set_address_un(addr, address);
239
 
        
240
 
        if (NULL != (s = strchr(address, ':'))) {
241
 
                gint ret;
242
 
                char *ip_address = g_strndup(address, s - address); /* may be NULL for strdup(..., 0) */
243
 
                char *port_err = NULL;
244
 
 
245
 
                guint port = strtoul(s + 1, &port_err, 10);
246
 
 
247
 
                if (*(s + 1) == '\0') {
248
 
                        g_critical("%s: IP-address has to be in the form [<ip>][:<port>], is '%s'. No port number",
249
 
                                        G_STRLOC, address);
250
 
                        ret = -1;
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);
254
 
                        ret = -1;
255
 
                } else {
256
 
                        ret = network_address_set_address_ip(addr, ip_address, port);
257
 
                }
258
 
 
259
 
                if (ip_address) g_free(ip_address);
 
155
        } else if (NULL != (s = strchr(address, ':'))) {
 
156
                gboolean ret;
 
157
                char *ip_address = g_strndup(address, s - address);
 
158
 
 
159
                guint port = strtoul(s + 1, NULL, 10);
 
160
 
 
161
                ret = network_address_set_address_ip(addr, ip_address, port);
 
162
 
 
163
                g_free(ip_address);
260
164
 
261
165
                return ret;
 
166
        } else { /* perhaps it is a plain IP address, lets add the default-port */
 
167
                return network_address_set_address_ip(addr, address, 3306);
262
168
        }
263
 
        /* perhaps it is a plain IP address, lets add the default-port */
264
 
        return network_address_set_address_ip(addr, address, 3306);
 
169
 
 
170
        g_assert_not_reached();
265
171
}
266
172
 
267
173
 
298
204
 */
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) {
301
 
#ifdef HAVE_SYS_UN_H
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 
306
 
                         *
307
 
                         * see #42220
308
 
                         */
309
 
                        return TRUE;
310
 
                }
311
 
#endif
312
207
                g_message("%s: is-local family %d != %d",
313
208
                                G_STRLOC,
314
209
                                src_addr->addr.common.sa_family,