View | Details | Raw Unified | Return to bug 88821 | Differences between
and this patch

Collapse All | Expand All

(-)ggate/ggatec/ggatec.c (-25 / +42 lines)
Lines 50-55 Link Here
50
#include <netinet/in.h>
50
#include <netinet/in.h>
51
#include <netinet/tcp.h>
51
#include <netinet/tcp.h>
52
#include <arpa/inet.h>
52
#include <arpa/inet.h>
53
#include <netdb.h>
53
54
54
#include <geom/gate/g_gate.h>
55
#include <geom/gate/g_gate.h>
55
#include "ggate.h"
56
#include "ggate.h"
Lines 63-69 Link Here
63
static unsigned flags = 0;
64
static unsigned flags = 0;
64
static int force = 0;
65
static int force = 0;
65
static unsigned queue_size = G_GATE_QUEUE_SIZE;
66
static unsigned queue_size = G_GATE_QUEUE_SIZE;
66
static unsigned port = G_GATE_PORT;
67
static const char *port = G_GATE_PORT_STR;
67
static off_t mediasize;
68
static off_t mediasize;
68
static unsigned sectorsize = 0;
69
static unsigned sectorsize = 0;
69
static unsigned timeout = G_GATE_TIMEOUT;
70
static unsigned timeout = G_GATE_TIMEOUT;
Lines 244-280 Link Here
244
	struct g_gate_version ver;
245
	struct g_gate_version ver;
245
	struct g_gate_cinit cinit;
246
	struct g_gate_cinit cinit;
246
	struct g_gate_sinit sinit;
247
	struct g_gate_sinit sinit;
247
	struct sockaddr_in serv;
248
	struct addrinfo hints;
249
	struct addrinfo *res, *p;
248
	int sfd;
250
	int sfd;
249
251
250
	/*
252
	/*
251
	 * Do the network stuff.
253
	 * Do the network stuff.
252
	 */
254
	 */
253
	bzero(&serv, sizeof(serv));
255
	bzero(&hints, sizeof(hints));
254
	serv.sin_family = AF_INET;
256
	hints.ai_family = PF_UNSPEC;
255
	serv.sin_addr.s_addr = g_gate_str2ip(host);
257
	hints.ai_socktype = SOCK_STREAM;
256
	if (serv.sin_addr.s_addr == INADDR_NONE) {
258
	sfd = -1;
257
		g_gate_log(LOG_DEBUG, "Invalid IP/host name: %s.", host);
259
	if (getaddrinfo(host, port, &hints, &res) != 0) {
260
		g_gate_log(LOG_DEBUG, "Invalid IP/host name or port: %s (%s).",
261
		    host, port);
258
		return (-1);
262
		return (-1);
259
	}
263
	} else {
260
	serv.sin_port = htons(port);
264
		p = res;
261
	sfd = socket(AF_INET, SOCK_STREAM, 0);
265
		while (p) {
262
	if (sfd == -1) {
266
			sfd = socket(p->ai_family, p->ai_socktype, 0);
263
		g_gate_log(LOG_DEBUG, "Cannot open socket: %s.",
267
			if (sfd == -1) {
264
		    strerror(errno));
268
				g_gate_log(LOG_DEBUG, "Cannot open socket: %s.",
265
		return (-1);
269
				    strerror(errno));
266
	}
270
				freeaddrinfo(res);
271
				return (-1);
272
			}
267
273
268
	g_gate_socket_settings(sfd);
274
			g_gate_socket_settings(sfd);
269
275
270
	if (connect(sfd, (struct sockaddr *)&serv, sizeof(serv)) == -1) {
276
			if (connect(sfd, p->ai_addr, p->ai_addrlen) == 0)
271
		g_gate_log(LOG_DEBUG, "Cannot connect to server: %s.",
277
				break;
272
		    strerror(errno));
278
273
		close(sfd);
279
			/* Non-critical error, try next address */
280
		        g_gate_log(LOG_DEBUG, "Cannot connect to server: %s.",
281
				strerror(errno));
282
			close(sfd);
283
			sfd = -1;
284
285
			p = p->ai_next;
286
		}
287
	}
288
	freeaddrinfo(res);
289
290
	if (sfd == -1) {
291
		g_gate_log(LOG_DEBUG, "Invalid IP/host name or port: %s (%s).",
292
		    host, port);
274
		return (-1);
293
		return (-1);
275
	}
294
	}
276
295
277
	g_gate_log(LOG_INFO, "Connected to the server: %s:%d.", host, port);
296
	g_gate_log(LOG_INFO, "Connected to the server: %s (%s).", host, port);
278
297
279
	/*
298
	/*
280
	 * Create and send version packet.
299
	 * Create and send version packet.
Lines 454-460 Link Here
454
	ggioc.gctl_maxcount = queue_size;
473
	ggioc.gctl_maxcount = queue_size;
455
	ggioc.gctl_timeout = timeout;
474
	ggioc.gctl_timeout = timeout;
456
	ggioc.gctl_unit = unit;
475
	ggioc.gctl_unit = unit;
457
	snprintf(ggioc.gctl_info, sizeof(ggioc.gctl_info), "%s:%u %s", host,
476
	snprintf(ggioc.gctl_info, sizeof(ggioc.gctl_info), "%s (%s) %s", host,
458
	    port, path);
477
	    port, path);
459
	g_gate_ioctl(G_GATE_CMD_CREATE, &ggioc);
478
	g_gate_ioctl(G_GATE_CMD_CREATE, &ggioc);
460
	if (unit == -1)
479
	if (unit == -1)
Lines 535-543 Link Here
535
			if (action != CREATE && action != RESCUE)
554
			if (action != CREATE && action != RESCUE)
536
				usage();
555
				usage();
537
			errno = 0;
556
			errno = 0;
538
			port = strtoul(optarg, NULL, 10);
557
			port = optarg;
539
			if (port == 0 && errno != 0)
540
				errx(EXIT_FAILURE, "Invalid port.");
541
			break;
558
			break;
542
		case 'q':
559
		case 'q':
543
			if (action != CREATE)
560
			if (action != CREATE)
(-)ggate/ggated/ggated.8 (-5 / +9 lines)
Lines 55-61 Link Here
55
Available options:
55
Available options:
56
.Bl -tag -width ".Ar exports\ file"
56
.Bl -tag -width ".Ar exports\ file"
57
.It Fl a Ar address
57
.It Fl a Ar address
58
Specifies an IP address to bind to.
58
Specifies an IP address to bind to.  To bind to multiple addresses,
59
specify each address with a separate
60
.Fl a
61
option.
59
.It Fl h
62
.It Fl h
60
Print available options.
63
Print available options.
61
.It Fl n
64
.It Fl n
Lines 74-80 Link Here
74
Size of send buffer to use.
77
Size of send buffer to use.
75
Default is 131072 (128kB).
78
Default is 131072 (128kB).
76
.It Fl v
79
.It Fl v
77
Do not fork, run in foreground and print debug informations on standard
80
Do not fork, run in foreground and print debug information on standard
78
output.
81
output.
79
.It Ar "exports file"
82
.It Ar "exports file"
80
An alternate location for the exports file.
83
An alternate location for the exports file.
Lines 82-90 Link Here
82
.Pp
85
.Pp
83
The format of an exports file is as follows:
86
The format of an exports file is as follows:
84
.Bd -literal -offset indent
87
.Bd -literal -offset indent
85
1.2.3.4		RO	/dev/acd0
88
1.2.3.4			RO	/dev/acd0
86
1.2.3.0/24	RW	/tmp/test.img
89
1.2.3.0/24		RW	/tmp/test.img
87
hostname	WO	/tmp/image
90
2001:DB8:17C0::/64	RW	/tmp/foo
91
hostname		WO	/tmp/image
88
.Ed
92
.Ed
89
.Sh EXIT STATUS
93
.Sh EXIT STATUS
90
Exit status is 0 on success, or 1 if the command fails.
94
Exit status is 0 on success, or 1 if the command fails.
(-)ggate/ggated/ggated.c (-126 / +279 lines)
Lines 44-49 Link Here
44
#include <netinet/in.h>
44
#include <netinet/in.h>
45
#include <netinet/tcp.h>
45
#include <netinet/tcp.h>
46
#include <arpa/inet.h>
46
#include <arpa/inet.h>
47
#include <netdb.h>
47
#include <signal.h>
48
#include <signal.h>
48
#include <assert.h>
49
#include <assert.h>
49
#include <err.h>
50
#include <err.h>
Lines 68-74 Link Here
68
	time_t		 c_birthtime;
69
	time_t		 c_birthtime;
69
	char		*c_path;
70
	char		*c_path;
70
	uint64_t	 c_token;
71
	uint64_t	 c_token;
71
	in_addr_t	 c_srcip;
72
	struct sockaddr_storage	 c_srcaddr;
72
	LIST_ENTRY(ggd_connection) c_next;
73
	LIST_ENTRY(ggd_connection) c_next;
73
};
74
};
74
75
Lines 83-98 Link Here
83
#define	r_error		r_hdr.gh_error
84
#define	r_error		r_hdr.gh_error
84
85
85
struct ggd_export {
86
struct ggd_export {
86
	char		*e_path;	/* path to device/file */
87
	char		        *e_path;	/* path to device/file */
87
	in_addr_t	 e_ip;		/* remote IP address */
88
	struct sockaddr_storage	 e_addr;	/* remote IP address */
88
	in_addr_t	 e_mask;	/* IP mask */
89
	struct sockaddr_storage	 e_mask;	/* IP mask */
89
	unsigned	 e_flags;	/* flags (RO/RW) */
90
	unsigned		 e_flags;	/* flags (RO/RW) */
90
	SLIST_ENTRY(ggd_export) e_next;
91
	SLIST_ENTRY(ggd_export)	 e_next;
92
};
93
94
struct ggd_listen {
95
	const char			*l_name;   /* host name / address */
96
	struct sockaddr_storage		 l_addr;   /* bind address & port */
97
	int				 l_fd;	   /* socket */
98
	SLIST_ENTRY(ggd_listen)		 l_next;
91
};
99
};
92
100
93
static const char *exports_file = GGATED_EXPORT_FILE;
101
static const char *exports_file = GGATED_EXPORT_FILE;
94
static int got_sighup = 0;
102
static int got_sighup = 0;
95
in_addr_t bindaddr;
96
103
97
static TAILQ_HEAD(, ggd_request) inqueue = TAILQ_HEAD_INITIALIZER(inqueue);
104
static TAILQ_HEAD(, ggd_request) inqueue = TAILQ_HEAD_INITIALIZER(inqueue);
98
static TAILQ_HEAD(, ggd_request) outqueue = TAILQ_HEAD_INITIALIZER(outqueue);
105
static TAILQ_HEAD(, ggd_request) outqueue = TAILQ_HEAD_INITIALIZER(outqueue);
Lines 115-185 Link Here
115
	exit(EXIT_FAILURE);
122
	exit(EXIT_FAILURE);
116
}
123
}
117
124
118
static char *
125
static const char *
119
ip2str(in_addr_t ip)
126
ip2str(struct sockaddr *addr)
120
{
127
{
121
	static char sip[16];
128
	static char sip[64];
129
130
	if (getnameinfo(addr, addr->sa_len, sip, sizeof(sip),
131
	    NULL, 0, NI_NUMERICHOST) == 0)
132
		return (sip);
122
133
123
	snprintf(sip, sizeof(sip), "%u.%u.%u.%u",
134
	return ("Unknown");
124
	    ((ip >> 24) & 0xff),
125
	    ((ip >> 16) & 0xff),
126
	    ((ip >> 8) & 0xff),
127
	    (ip & 0xff));
128
	return (sip);
129
}
135
}
130
136
131
static in_addr_t
137
static struct sockaddr_storage
132
countmask(unsigned m)
138
countmask(struct sockaddr* addr, int mask)	/* also normalizes addr */
133
{
139
{
134
	in_addr_t mask;
140
	struct sockaddr_storage ss;
141
	int i, alen;
142
	unsigned char *mp, *ap;
135
143
136
	if (m == 0) {
144
	bzero(&ss, sizeof(ss));
137
		mask = 0x0;
145
	ss.ss_family = addr->sa_family;
138
	} else {
146
	ss.ss_len = addr->sa_len;
139
		mask = 1 << (32 - m);
147
140
		mask--;
148
	switch (addr->sa_family) {
141
		mask = ~mask;
149
		case AF_INET:
150
			alen = 4;	/* 32 bits */
151
			ap = (unsigned char*)&((struct sockaddr_in*)addr)->sin_addr.s_addr;
152
			mp = (unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr;
153
			break;
154
		case AF_INET6:
155
			alen = 16;	/* 128 bits */
156
			ap = (unsigned char*)&((struct sockaddr_in6*)addr)->sin6_addr.s6_addr;
157
			mp = (unsigned char*)&((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr;
158
			break;
159
		default:
160
			g_gate_xlog("Unknown address family in countmask");
161
	}
162
163
	i = 0;
164
	while (mask > 0 && i < alen) {
165
		if (mask < 8) {
166
			mp[i] = ~(0xff >> mask);
167
			ap[i] &= mp[i];
168
		} else
169
			mp[i] = 0xff;
170
		i++;
171
		mask -= 8;
142
	}
172
	}
143
	return (mask);
173
	while (i < alen) {		/* zero out remaining bits of addr */
174
		ap[i] = 0;
175
		i++;
176
	}
177
178
	return (ss);
144
}
179
}
145
180
146
static void
181
static void
147
line_parse(char *line, unsigned lineno)
182
line_parse(char *line, unsigned lineno)
148
{
183
{
149
	struct ggd_export *ex;
184
	struct ggd_export *ex;
150
	char *word, *path, *sflags;
185
	char *pmask, *word, *path, *sflags;
151
	unsigned flags, i, vmask;
186
	unsigned flags, i;
152
	in_addr_t ip, mask;
187
	int vmask;
188
	struct addrinfo hints, *res, *p;
153
189
154
	ip = mask = flags = vmask = 0;
190
	flags = vmask = 0;
155
	path = NULL;
191
	path = NULL;
156
	sflags = NULL;
192
	sflags = NULL;
193
	pmask = NULL;
157
194
158
	for (i = 0, word = strtok(line, " \t"); word != NULL;
195
	for (i = 0, word = strtok(line, " \t"); word != NULL;
159
	    i++, word = strtok(NULL, " \t")) {
196
	    i++, word = strtok(NULL, " \t")) {
160
		switch (i) {
197
		switch (i) {
161
		case 0: /* IP address or host name */
198
		case 0: /* IP address or host name */
162
			ip = g_gate_str2ip(strsep(&word, "/"));
199
			bzero(&hints, sizeof(hints));
163
			if (ip == INADDR_NONE) {
200
			hints.ai_family = PF_UNSPEC;
201
			hints.ai_socktype = SOCK_STREAM;
202
			if (getaddrinfo(strsep(&word, "/"), NULL, &hints,
203
			    &res) != 0)
164
				g_gate_xlog("Invalid IP/host name at line %u.",
204
				g_gate_xlog("Invalid IP/host name at line %u.",
165
				    lineno);
205
				    lineno);
166
			}
206
			pmask = word;
167
			ip = ntohl(ip);
168
			if (word == NULL)
169
				vmask = 32;
170
			else {
171
				errno = 0;
172
				vmask = strtoul(word, NULL, 10);
173
				if (vmask == 0 && errno != 0) {
174
					g_gate_xlog("Invalid IP mask value at "
175
					    "line %u.", lineno);
176
				}
177
				if ((unsigned)vmask > 32) {
178
					g_gate_xlog("Invalid IP mask value at line %u.",
179
					    lineno);
180
				}
181
			}
182
			mask = countmask(vmask);
183
			break;
207
			break;
184
		case 1:	/* flags */
208
		case 1:	/* flags */
185
			if (strcasecmp("rd", word) == 0 ||
209
			if (strcasecmp("rd", word) == 0 ||
Lines 209-230 Link Here
209
	if (i != 3)
233
	if (i != 3)
210
		g_gate_xlog("Too few arguments at line %u.", lineno);
234
		g_gate_xlog("Too few arguments at line %u.", lineno);
211
235
212
	ex = malloc(sizeof(*ex));
236
	p = res;
213
	if (ex == NULL)
237
	while (p) {
214
		g_gate_xlog("No enough memory.");
238
		ex = malloc(sizeof(*ex));
215
	ex->e_path = strdup(path);
239
		if (ex == NULL)
216
	if (ex->e_path == NULL)
240
			g_gate_xlog("Not enough memory.");
217
		g_gate_xlog("No enough memory.");
241
		ex->e_path = strdup(path);
218
242
		if (ex->e_path == NULL)
219
	/* Made 'and' here. */
243
			g_gate_xlog("Not enough memory.");
220
	ex->e_ip = (ip & mask);
244
221
	ex->e_mask = mask;
245
		if (pmask == NULL && p->ai_family == AF_INET6)
222
	ex->e_flags = flags;
246
			vmask = 128;
247
		else if (pmask == NULL)
248
			vmask = 32;
249
		else {
250
			errno = 0;
251
			vmask = strtoul(pmask, NULL, 10);
252
			if (vmask == 0 && errno != 0) {
253
				g_gate_xlog("Invalid IP mask value at "
254
				    "line %u.", lineno);
255
			}
256
		}
257
258
		if ((vmask > 32 && p->ai_family == AF_INET) ||
259
		    (vmask > 128 && p->ai_family == AF_INET6))
260
			g_gate_xlog("Invalid IP mask value at line %u",
261
			    lineno);
262
263
		memcpy(&ex->e_addr, p->ai_addr, p->ai_addrlen);
264
		ex->e_mask = countmask((struct sockaddr*)&ex->e_addr, vmask);
265
		ex->e_flags = flags;
266
267
		SLIST_INSERT_HEAD(&exports, ex, e_next);
223
268
224
	SLIST_INSERT_HEAD(&exports, ex, e_next);
269
		g_gate_log(LOG_DEBUG, "Added %s/%u %s %s to exports list.",
270
		    ip2str((struct sockaddr*)&ex->e_addr), vmask, path, sflags);
225
271
226
	g_gate_log(LOG_DEBUG, "Added %s/%u %s %s to exports list.",
272
		p = p->ai_next;
227
	    ip2str(ex->e_ip), vmask, path, sflags);
273
	}
274
275
	freeaddrinfo(res);
228
}
276
}
229
277
230
static void
278
static void
Lines 302-313 Link Here
302
exports_check(struct ggd_export *ex, struct g_gate_cinit *cinit,
350
exports_check(struct ggd_export *ex, struct g_gate_cinit *cinit,
303
    struct ggd_connection *conn)
351
    struct ggd_connection *conn)
304
{
352
{
305
	char ipmask[32]; /* 32 == strlen("xxx.xxx.xxx.xxx/xxx.xxx.xxx.xxx")+1 */
353
	char ipmask[80]; /* 80 == strlen("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")+1 */
306
	int error = 0, flags;
354
	int error = 0, flags;
307
355
308
	strlcpy(ipmask, ip2str(ex->e_ip), sizeof(ipmask));
356
	strlcpy(ipmask, ip2str((struct sockaddr*)&ex->e_addr), sizeof(ipmask));
309
	strlcat(ipmask, "/", sizeof(ipmask));
357
	strlcat(ipmask, "/", sizeof(ipmask));
310
	strlcat(ipmask, ip2str(ex->e_mask), sizeof(ipmask));
358
	strlcat(ipmask, ip2str((struct sockaddr*)&ex->e_mask), sizeof(ipmask));
311
	if ((cinit->gc_flags & GGATE_FLAG_RDONLY) != 0) {
359
	if ((cinit->gc_flags & GGATE_FLAG_RDONLY) != 0) {
312
		if (ex->e_flags == O_WRONLY) {
360
		if (ex->e_flags == O_WRONLY) {
313
			g_gate_log(LOG_WARNING, "Read-only access requested, "
361
			g_gate_log(LOG_WARNING, "Read-only access requested, "
Lines 355-371 Link Here
355
	return (0);
403
	return (0);
356
}
404
}
357
405
406
static int
407
mask_compare(struct sockaddr *a, struct sockaddr *b, struct sockaddr *m) {
408
	unsigned char *ap, *bp, *mp;
409
	int alen;
410
	if (a->sa_family != m->sa_family || b->sa_family != m->sa_family)
411
		return (0);
412
413
	switch (m->sa_family) {
414
		case AF_INET:
415
			alen = 4;
416
			ap = (unsigned char*)&((struct sockaddr_in*)a)->sin_addr.s_addr;
417
			bp = (unsigned char*)&((struct sockaddr_in*)b)->sin_addr.s_addr;
418
			mp = (unsigned char*)&((struct sockaddr_in*)m)->sin_addr.s_addr;
419
			break;
420
		case AF_INET6:
421
			alen = 16;
422
			ap = (unsigned char*)&((struct sockaddr_in6*)a)->sin6_addr.s6_addr;
423
			bp = (unsigned char*)&((struct sockaddr_in6*)b)->sin6_addr.s6_addr;
424
			mp = (unsigned char*)&((struct sockaddr_in6*)m)->sin6_addr.s6_addr;
425
			break;
426
		default:
427
			return (0);
428
	}
429
430
	while (alen > 0) {
431
		if ((*ap & *mp) != (*bp & *mp))
432
			return (0);
433
		
434
		ap++;
435
		bp++;
436
		mp++;
437
		alen--;
438
	}
439
440
	return (1);
441
}
442
358
static struct ggd_export *
443
static struct ggd_export *
359
exports_find(struct sockaddr *s, struct g_gate_cinit *cinit,
444
exports_find(struct sockaddr *s, struct g_gate_cinit *cinit,
360
    struct ggd_connection *conn)
445
    struct ggd_connection *conn)
361
{
446
{
362
	struct ggd_export *ex;
447
	struct ggd_export *ex;
363
	in_addr_t ip;
364
	int error;
448
	int error;
365
449
366
	ip = htonl(((struct sockaddr_in *)(void *)s)->sin_addr.s_addr);
367
	SLIST_FOREACH(ex, &exports, e_next) {
450
	SLIST_FOREACH(ex, &exports, e_next) {
368
		if ((ip & ex->e_mask) != ex->e_ip) {
451
		if (!mask_compare(s, (struct sockaddr*)&ex->e_addr,
452
				 (struct sockaddr*)&ex->e_mask)) {
369
			g_gate_log(LOG_DEBUG, "exports[%s]: IP mismatch.",
453
			g_gate_log(LOG_DEBUG, "exports[%s]: IP mismatch.",
370
			    ex->e_path);
454
			    ex->e_path);
371
			continue;
455
			continue;
Lines 384-390 Link Here
384
		}
468
		}
385
	}
469
	}
386
	g_gate_log(LOG_WARNING, "Unauthorized connection from: %s.",
470
	g_gate_log(LOG_WARNING, "Unauthorized connection from: %s.",
387
	    ip2str(ip));
471
	    ip2str(s));
388
	errno = EPERM;
472
	errno = EPERM;
389
	return (NULL);
473
	return (NULL);
390
}
474
}
Lines 404-410 Link Here
404
			LIST_REMOVE(conn, c_next);
488
			LIST_REMOVE(conn, c_next);
405
			g_gate_log(LOG_NOTICE,
489
			g_gate_log(LOG_NOTICE,
406
			    "Connection from %s [%s] removed.",
490
			    "Connection from %s [%s] removed.",
407
			    ip2str(conn->c_srcip), conn->c_path);
491
			    ip2str((struct sockaddr*)&conn->c_srcaddr),
492
			    conn->c_path);
408
			close(conn->c_diskfd);
493
			close(conn->c_diskfd);
409
			close(conn->c_sendfd);
494
			close(conn->c_sendfd);
410
			close(conn->c_recvfd);
495
			close(conn->c_recvfd);
Lines 430-436 Link Here
430
connection_new(struct g_gate_cinit *cinit, struct sockaddr *s, int sfd)
515
connection_new(struct g_gate_cinit *cinit, struct sockaddr *s, int sfd)
431
{
516
{
432
	struct ggd_connection *conn;
517
	struct ggd_connection *conn;
433
	in_addr_t ip;
434
518
435
	/*
519
	/*
436
	 * First, look for old connections.
520
	 * First, look for old connections.
Lines 449-456 Link Here
449
		return (NULL);
533
		return (NULL);
450
	}
534
	}
451
	conn->c_token = cinit->gc_token;
535
	conn->c_token = cinit->gc_token;
452
	ip = htonl(((struct sockaddr_in *)(void *)s)->sin_addr.s_addr);
536
	memcpy(&conn->c_srcaddr, s, s->sa_len);
453
	conn->c_srcip = ip;
454
	conn->c_sendfd = conn->c_recvfd = -1;
537
	conn->c_sendfd = conn->c_recvfd = -1;
455
	if ((cinit->gc_flags & GGATE_FLAG_SEND) != 0)
538
	if ((cinit->gc_flags & GGATE_FLAG_SEND) != 0)
456
		conn->c_sendfd = sfd;
539
		conn->c_sendfd = sfd;
Lines 461-467 Link Here
461
	time(&conn->c_birthtime);
544
	time(&conn->c_birthtime);
462
	conn->c_flags = cinit->gc_flags;
545
	conn->c_flags = cinit->gc_flags;
463
	LIST_INSERT_HEAD(&connections, conn, c_next);
546
	LIST_INSERT_HEAD(&connections, conn, c_next);
464
	g_gate_log(LOG_DEBUG, "Connection created [%s, %s].", ip2str(ip),
547
	g_gate_log(LOG_DEBUG, "Connection created [%s, %s].", ip2str(s),
465
	    conn->c_path);
548
	    conn->c_path);
466
	return (conn);
549
	return (conn);
467
}
550
}
Lines 470-482 Link Here
470
connection_add(struct ggd_connection *conn, struct g_gate_cinit *cinit,
553
connection_add(struct ggd_connection *conn, struct g_gate_cinit *cinit,
471
    struct sockaddr *s, int sfd)
554
    struct sockaddr *s, int sfd)
472
{
555
{
473
	in_addr_t ip;
474
475
	ip = htonl(((struct sockaddr_in *)(void *)s)->sin_addr.s_addr);
476
	if ((cinit->gc_flags & GGATE_FLAG_SEND) != 0) {
556
	if ((cinit->gc_flags & GGATE_FLAG_SEND) != 0) {
477
		if (conn->c_sendfd != -1) {
557
		if (conn->c_sendfd != -1) {
478
			g_gate_log(LOG_WARNING,
558
			g_gate_log(LOG_WARNING,
479
			    "Send socket already exists [%s, %s].", ip2str(ip),
559
			    "Send socket already exists [%s, %s].", ip2str(s),
480
			    conn->c_path);
560
			    conn->c_path);
481
			return (EEXIST);
561
			return (EEXIST);
482
		}
562
		}
Lines 485-496 Link Here
485
		if (conn->c_recvfd != -1) {
565
		if (conn->c_recvfd != -1) {
486
			g_gate_log(LOG_WARNING,
566
			g_gate_log(LOG_WARNING,
487
			    "Receive socket already exists [%s, %s].",
567
			    "Receive socket already exists [%s, %s].",
488
			    ip2str(ip), conn->c_path);
568
			    ip2str(s), conn->c_path);
489
			return (EEXIST);
569
			return (EEXIST);
490
		}
570
		}
491
		conn->c_recvfd = sfd;
571
		conn->c_recvfd = sfd;
492
	}
572
	}
493
	g_gate_log(LOG_DEBUG, "Connection added [%s, %s].", ip2str(ip),
573
	g_gate_log(LOG_DEBUG, "Connection added [%s, %s].", ip2str(s),
494
	    conn->c_path);
574
	    conn->c_path);
495
	return (0);
575
	return (0);
496
}
576
}
Lines 505-511 Link Here
505
585
506
	LIST_REMOVE(conn, c_next);
586
	LIST_REMOVE(conn, c_next);
507
	g_gate_log(LOG_DEBUG, "Connection removed [%s %s].",
587
	g_gate_log(LOG_DEBUG, "Connection removed [%s %s].",
508
	    ip2str(conn->c_srcip), conn->c_path);
588
	    ip2str((struct sockaddr*)&conn->c_srcaddr), conn->c_path);
509
	if (conn->c_sendfd != -1)
589
	if (conn->c_sendfd != -1)
510
		close(conn->c_sendfd);
590
		close(conn->c_sendfd);
511
	if (conn->c_recvfd != -1)
591
	if (conn->c_recvfd != -1)
Lines 815-824 Link Here
815
static void
895
static void
816
log_connection(struct sockaddr *from)
896
log_connection(struct sockaddr *from)
817
{
897
{
818
	in_addr_t ip;
898
	g_gate_log(LOG_INFO, "Connection from: %s.", ip2str(from));
819
820
	ip = htonl(((struct sockaddr_in *)(void *)from)->sin_addr.s_addr);
821
	g_gate_log(LOG_INFO, "Connection from: %s.", ip2str(ip));
822
}
899
}
823
900
824
static int
901
static int
Lines 940-953 Link Here
940
int
1017
int
941
main(int argc, char *argv[])
1018
main(int argc, char *argv[])
942
{
1019
{
943
	struct sockaddr_in serv;
1020
	SLIST_HEAD(, ggd_listen) listens = SLIST_HEAD_INITIALIZER(&listens);
944
	struct sockaddr from;
1021
	struct ggd_listen *cl, *nl;
1022
	struct addrinfo hints, *res, *p;
1023
	struct sockaddr_storage from;
945
	socklen_t fromlen;
1024
	socklen_t fromlen;
946
	int sfd, tmpsfd;
1025
	int maxfd, tmpsfd;
947
	unsigned port;
1026
	fd_set listenfds;
1027
	const char *port;
948
1028
949
	bindaddr = htonl(INADDR_ANY);
1029
	port = G_GATE_PORT_STR;
950
	port = G_GATE_PORT;
951
	for (;;) {
1030
	for (;;) {
952
		int ch;
1031
		int ch;
953
1032
Lines 956-975 Link Here
956
			break;
1035
			break;
957
		switch (ch) {
1036
		switch (ch) {
958
		case 'a':
1037
		case 'a':
959
			bindaddr = g_gate_str2ip(optarg);
1038
			nl = malloc(sizeof(*nl));
960
			if (bindaddr == INADDR_NONE) {
1039
			bzero(nl, sizeof(*nl));
961
				errx(EXIT_FAILURE,
1040
			nl->l_name = optarg;
962
				    "Invalid IP/host name to bind to.");
1041
			/* delay resolution until we know port number */
963
			}
1042
			SLIST_INSERT_HEAD(&listens, nl, l_next);
964
			break;
1043
			break;
965
		case 'n':
1044
		case 'n':
966
			nagle = 0;
1045
			nagle = 0;
967
			break;
1046
			break;
968
		case 'p':
1047
		case 'p':
969
			errno = 0;
1048
			port = optarg;
970
			port = strtoul(optarg, NULL, 10);
971
			if (port == 0 && errno != 0)
972
				errx(EXIT_FAILURE, "Invalid port.");
973
			break;
1049
			break;
974
		case 'R':
1050
		case 'R':
975
			errno = 0;
1051
			errno = 0;
Lines 998-1003 Link Here
998
		exports_file = argv[0];
1074
		exports_file = argv[0];
999
	exports_get();
1075
	exports_get();
1000
1076
1077
	if (SLIST_EMPTY(&listens)) {
1078
		/* Bind to all address families */
1079
		bzero(&hints, sizeof(hints));
1080
		hints.ai_family = PF_UNSPEC;
1081
		hints.ai_flags = AI_PASSIVE;
1082
		hints.ai_socktype = SOCK_STREAM;
1083
		if (getaddrinfo(NULL, port, &hints, &res))
1084
			g_gate_xlog("Cannot get passive address: %s",
1085
			    strerror(errno));
1086
1087
		p = res;
1088
		while (p) {
1089
			nl = malloc(sizeof(*nl));
1090
			bzero(nl, sizeof(*nl));
1091
			memcpy(&nl->l_addr, p->ai_addr, p->ai_addrlen);
1092
			SLIST_INSERT_HEAD(&listens, nl, l_next);
1093
			
1094
			p = p->ai_next;
1095
		}
1096
		freeaddrinfo(res);
1097
	} else {
1098
		/* Bind to some specific addresses */
1099
		SLIST_FOREACH(cl, &listens, l_next) {
1100
			bzero(&hints, sizeof(hints));
1101
			hints.ai_family = PF_UNSPEC;
1102
			hints.ai_socktype = SOCK_STREAM;
1103
			if (getaddrinfo(cl->l_name, port, &hints, &res))
1104
				g_gate_xlog("Invalid IP/host name to bind to: "
1105
				    "%s", cl->l_name);
1106
1107
			/* Re-use current list entry for first match, add
1108
			 * new ones after that */
1109
			p = res;
1110
			nl = cl;
1111
			while (p) {
1112
				if (p != res) {
1113
					nl = malloc(sizeof(*nl));
1114
					bzero(nl, sizeof(*nl));
1115
				}
1116
1117
				memcpy(&nl->l_addr, p->ai_addr, p->ai_addrlen);
1118
1119
				if (p != res) {
1120
					SLIST_INSERT_HEAD(&listens, nl, l_next);
1121
				}
1122
				p = p->ai_next;
1123
			}
1124
			freeaddrinfo(res);
1125
		}
1126
	}
1127
1128
	/* Actually create sockets and bind to them */
1129
	maxfd = 0;
1130
	SLIST_FOREACH(cl, &listens, l_next) {
1131
		cl->l_fd = socket(cl->l_addr.ss_family, SOCK_STREAM, 0);
1132
		if (cl->l_fd == -1)
1133
			g_gate_xlog("Cannot open stream socket: %s.",
1134
			    strerror(errno));
1135
		g_gate_socket_settings(cl->l_fd);
1136
1137
		if (bind(cl->l_fd, (struct sockaddr *)&cl->l_addr,
1138
		    cl->l_addr.ss_len) == -1)
1139
			g_gate_xlog("bind(): %s.", strerror(errno));
1140
		if (listen(cl->l_fd, 5) == -1)
1141
			g_gate_xlog("listen(): %s.", strerror(errno));
1142
1143
		if (maxfd <= cl->l_fd)
1144
			maxfd = cl->l_fd + 1;
1145
1146
		g_gate_log(LOG_INFO, "Listen on address: %s (%s).",
1147
			ip2str((struct sockaddr *)&cl->l_addr), port);
1148
	}
1149
1001
	if (!g_gate_verbose) {
1150
	if (!g_gate_verbose) {
1002
		/* Run in daemon mode. */
1151
		/* Run in daemon mode. */
1003
		if (daemon(0, 0) == -1)
1152
		if (daemon(0, 0) == -1)
Lines 1005-1044 Link Here
1005
	}
1154
	}
1006
1155
1007
	signal(SIGCHLD, SIG_IGN);
1156
	signal(SIGCHLD, SIG_IGN);
1008
1009
	sfd = socket(AF_INET, SOCK_STREAM, 0);
1010
	if (sfd == -1)
1011
		g_gate_xlog("Cannot open stream socket: %s.", strerror(errno));
1012
	bzero(&serv, sizeof(serv));
1013
	serv.sin_family = AF_INET;
1014
	serv.sin_addr.s_addr = bindaddr;
1015
	serv.sin_port = htons(port);
1016
1017
	g_gate_socket_settings(sfd);
1018
1019
	if (bind(sfd, (struct sockaddr *)&serv, sizeof(serv)) == -1)
1020
		g_gate_xlog("bind(): %s.", strerror(errno));
1021
	if (listen(sfd, 5) == -1)
1022
		g_gate_xlog("listen(): %s.", strerror(errno));
1023
1024
	g_gate_log(LOG_INFO, "Listen on port: %d.", port);
1025
1026
	signal(SIGHUP, huphandler);
1157
	signal(SIGHUP, huphandler);
1027
1158
1028
	for (;;) {
1159
	for (;;) {
1029
		fromlen = sizeof(from);
1160
		FD_ZERO(&listenfds);
1030
		tmpsfd = accept(sfd, &from, &fromlen);
1161
		SLIST_FOREACH(cl, &listens, l_next) {
1031
		if (tmpsfd == -1)
1162
			FD_SET(cl->l_fd, &listenfds);
1032
			g_gate_xlog("accept(): %s.", strerror(errno));
1163
		}
1164
1165
		select(maxfd, &listenfds, NULL, NULL, NULL);
1033
1166
1034
		if (got_sighup) {
1167
		if (got_sighup) {
1035
			got_sighup = 0;
1168
			got_sighup = 0;
1036
			exports_get();
1169
			exports_get();
1037
		}
1170
		}
1038
1171
1039
		if (!handshake(&from, tmpsfd))
1172
		SLIST_FOREACH(cl, &listens, l_next) {
1040
			close(tmpsfd);
1173
			if (!FD_ISSET(cl->l_fd, &listenfds))
1174
				continue;
1175
1176
			fromlen = sizeof(from);
1177
			tmpsfd = accept(cl->l_fd, (struct sockaddr*)&from,
1178
			    &fromlen);
1179
1180
			if (tmpsfd == -1) {
1181
				g_gate_log(LOG_WARNING, "accept(): %s.",
1182
				    strerror(errno));
1183
				continue;
1184
			}
1185
1186
			if (!handshake((struct sockaddr*)&from, tmpsfd))
1187
				close(tmpsfd);
1188
		}
1189
	}
1190
	while (!SLIST_EMPTY(&listens)) {
1191
		cl = SLIST_FIRST(&listens);
1192
		close(cl->l_fd);
1193
		SLIST_REMOVE_HEAD(&listens, l_next);
1194
		free(cl);
1041
	}
1195
	}
1042
	close(sfd);
1043
	exit(EXIT_SUCCESS);
1196
	exit(EXIT_SUCCESS);
1044
}
1197
}
(-)ggate/shared/ggate.c (-18 lines)
Lines 375-395 Link Here
375
	exit(EXIT_SUCCESS);
375
	exit(EXIT_SUCCESS);
376
}
376
}
377
#endif	/* LIBGEOM */
377
#endif	/* LIBGEOM */
378
379
in_addr_t
380
g_gate_str2ip(const char *str)
381
{
382
	struct hostent *hp;
383
	in_addr_t ip;
384
385
	ip = inet_addr(str);
386
	if (ip != INADDR_NONE) {
387
		/* It is a valid IP address. */
388
		return (ip);
389
	}
390
	/* Check if it is a valid host name. */
391
	hp = gethostbyname(str);
392
	if (hp == NULL)
393
		return (INADDR_NONE);
394
	return (((struct in_addr *)(void *)hp->h_addr)->s_addr);
395
}
(-)ggate/shared/ggate.h (-1 / +1 lines)
Lines 33-38 Link Here
33
#include <stdarg.h>
33
#include <stdarg.h>
34
34
35
#define	G_GATE_PORT		3080
35
#define	G_GATE_PORT		3080
36
#define	G_GATE_PORT_STR		"3080"
36
37
37
#define	G_GATE_RCVBUF		131072
38
#define	G_GATE_RCVBUF		131072
38
#define	G_GATE_SNDBUF		131072
39
#define	G_GATE_SNDBUF		131072
Lines 110-116 Link Here
110
#ifdef LIBGEOM
111
#ifdef LIBGEOM
111
void	g_gate_list(int unit, int verbose);
112
void	g_gate_list(int unit, int verbose);
112
#endif
113
#endif
113
in_addr_t g_gate_str2ip(const char *str);
114
114
115
/*
115
/*
116
 * g_gate_swap2h_* - functions swap bytes to host byte order (from big endian).
116
 * g_gate_swap2h_* - functions swap bytes to host byte order (from big endian).

Return to bug 88821