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

Collapse All | Expand All

(-)ggatec/ggatec.c (-36 / +133 lines)
Lines 49-55 Link Here
49
#include <sys/bio.h>
49
#include <sys/bio.h>
50
#include <netinet/in.h>
50
#include <netinet/in.h>
51
#include <netinet/tcp.h>
51
#include <netinet/tcp.h>
52
#include <netinet/sctp.h>
52
#include <arpa/inet.h>
53
#include <arpa/inet.h>
54
#include <netdb.h>
53
55
54
#include <geom/gate/g_gate.h>
56
#include <geom/gate/g_gate.h>
55
#include "ggate.h"
57
#include "ggate.h"
Lines 61-69 Link Here
61
static const char *host = NULL;
63
static const char *host = NULL;
62
static int unit = -1;
64
static int unit = -1;
63
static unsigned flags = 0;
65
static unsigned flags = 0;
66
/* destroy -f => force, create/rescue -f => foreground */
64
static int force = 0;
67
static int force = 0;
68
static int foreground = 0;
65
static unsigned queue_size = G_GATE_QUEUE_SIZE;
69
static unsigned queue_size = G_GATE_QUEUE_SIZE;
66
static unsigned port = G_GATE_PORT;
70
static const char *port = G_GATE_PORT_STR;
67
static off_t mediasize;
71
static off_t mediasize;
68
static unsigned sectorsize = 0;
72
static unsigned sectorsize = 0;
69
static unsigned timeout = G_GATE_TIMEOUT;
73
static unsigned timeout = G_GATE_TIMEOUT;
Lines 71-91 Link Here
71
static uint32_t token;
75
static uint32_t token;
72
static pthread_t sendtd, recvtd;
76
static pthread_t sendtd, recvtd;
73
static int reconnect;
77
static int reconnect;
78
static struct addrinfo hints;
79
static int ai_protocol = 0; /* 0 for TCP and IPPROTO_SCTP for SCTP */
80
81
static uint64_t send_seq;
82
static uint64_t recv_seq;
74
83
75
static void
84
static void
76
usage(void)
85
usage(void)
77
{
86
{
78
87
79
	fprintf(stderr, "usage: %s create [-nv] [-o <ro|wo|rw>] [-p port] "
88
	fprintf(stderr, "usage: %s create [-fnv] [-o <ro|wo|rw>] [-p port] "
80
	    "[-q queue_size] [-R rcvbuf] [-S sndbuf] [-s sectorsize] "
89
	    "[-q queue_size] [-R rcvbuf] [-S sndbuf] [-s sectorsize] "
81
	    "[-t timeout] [-u unit] <host> <path>\n", getprogname());
90
	    "[-t timeout] [-u unit] [-F <0|4|6>] [-P protocol] <host> <path>\n",
82
	fprintf(stderr, "       %s rescue [-nv] [-o <ro|wo|rw>] [-p port] "
91
	    getprogname());
83
	    "[-R rcvbuf] [-S sndbuf] <-u unit> <host> <path>\n", getprogname());
92
	fprintf(stderr, "       %s rescue [-fnv] [-o <ro|wo|rw>] [-p port] "
93
	    "[-R rcvbuf] [-S sndbuf] [-F <0|4|6>] [-P protocol] <-u unit> <host> <path>\n",
94
	    getprogname());
84
	fprintf(stderr, "       %s destroy [-f] <-u unit>\n", getprogname());
95
	fprintf(stderr, "       %s destroy [-f] <-u unit>\n", getprogname());
85
	fprintf(stderr, "       %s list [-v] [-u unit]\n", getprogname());
96
	fprintf(stderr, "       %s list [-v] [-u unit]\n", getprogname());
86
	exit(EXIT_FAILURE);
97
	exit(EXIT_FAILURE);
87
}
98
}
88
99
100
static void
101
summary(void)
102
{
103
	char buf[1024];
104
105
	/* Use snprintf(3) so that we don't reenter stdio(3). */
106
	snprintf(buf, sizeof(buf),
107
	    "last send seq %llu\n"
108
	    "last recv seq %llu\n"
109
	    "",
110
	    send_seq, recv_seq);
111
	write(STDERR_FILENO, buf, strlen(buf));
112
}
113
114
static void
115
summaryx(int notused __unused)
116
{
117
	int save_errno = errno;
118
119
	summary();
120
	errno = save_errno;
121
}
122
89
static void *
123
static void *
90
send_thread(void *arg __unused)
124
send_thread(void *arg __unused)
91
{
125
{
Lines 150-157 Link Here
150
		g_gate_swap2n_hdr(&hdr);
184
		g_gate_swap2n_hdr(&hdr);
151
185
152
		data = g_gate_send(sendfd, &hdr, sizeof(hdr), MSG_NOSIGNAL);
186
		data = g_gate_send(sendfd, &hdr, sizeof(hdr), MSG_NOSIGNAL);
153
		g_gate_log(LOG_DEBUG, "Sent hdr packet.");
154
		g_gate_swap2h_hdr(&hdr);
187
		g_gate_swap2h_hdr(&hdr);
188
		g_gate_log(LOG_DEBUG, "Sent hdr packet (seq=%llu).", hdr.gh_seq);
189
		send_seq = hdr.gh_seq;
190
155
		if (reconnect)
191
		if (reconnect)
156
			break;
192
			break;
157
		if (data != sizeof(hdr)) {
193
		if (data != sizeof(hdr)) {
Lines 172-179 Link Here
172
				pthread_kill(recvtd, SIGUSR1);
208
				pthread_kill(recvtd, SIGUSR1);
173
				break;
209
				break;
174
			}
210
			}
175
			g_gate_log(LOG_DEBUG, "Sent %zd bytes (offset=%llu, "
211
			g_gate_log(LOG_DEBUG, "Sent %zd bytes (seq=%llu, offset=%llu, "
176
			    "size=%u).", data, hdr.gh_offset, hdr.gh_length);
212
			    "size=%u).", data, hdr.gh_seq, hdr.gh_offset, hdr.gh_length);
177
		}
213
		}
178
	}
214
	}
179
	g_gate_log(LOG_DEBUG, "%s: Died.", __func__);
215
	g_gate_log(LOG_DEBUG, "%s: Died.", __func__);
Lines 207-213 Link Here
207
			pthread_kill(sendtd, SIGUSR1);
243
			pthread_kill(sendtd, SIGUSR1);
208
			break;
244
			break;
209
		}
245
		}
210
		g_gate_log(LOG_DEBUG, "Received hdr packet.");
246
		g_gate_log(LOG_DEBUG, "Received hdr packet (seq=%llu).", hdr.gh_seq);
247
		recv_seq = hdr.gh_seq;
211
248
212
		ggio.gctl_seq = hdr.gh_seq;
249
		ggio.gctl_seq = hdr.gh_seq;
213
		ggio.gctl_cmd = hdr.gh_cmd;
250
		ggio.gctl_cmd = hdr.gh_cmd;
Lines 216-221 Link Here
216
		ggio.gctl_error = hdr.gh_error;
253
		ggio.gctl_error = hdr.gh_error;
217
254
218
		if (ggio.gctl_error == 0 && ggio.gctl_cmd == GGATE_CMD_READ) {
255
		if (ggio.gctl_error == 0 && ggio.gctl_cmd == GGATE_CMD_READ) {
256
g_gate_log(LOG_DEBUG, "Received READ packet.");
219
			data = g_gate_recv(recvfd, ggio.gctl_data,
257
			data = g_gate_recv(recvfd, ggio.gctl_data,
220
			    ggio.gctl_length, MSG_WAITALL);
258
			    ggio.gctl_length, MSG_WAITALL);
221
			if (reconnect)
259
			if (reconnect)
Lines 244-280 Link Here
244
	struct g_gate_version ver;
282
	struct g_gate_version ver;
245
	struct g_gate_cinit cinit;
283
	struct g_gate_cinit cinit;
246
	struct g_gate_sinit sinit;
284
	struct g_gate_sinit sinit;
247
	struct sockaddr_in serv;
285
	struct addrinfo *res, *p;
248
	int sfd;
286
	int sfd;
287
	int error = 0;
249
288
250
	/*
289
	/*
251
	 * Do the network stuff.
290
	 * Do the network stuff.
252
	 */
291
	 */
253
	bzero(&serv, sizeof(serv));
292
	sfd = -1;
254
	serv.sin_family = AF_INET;
293
	if ((error = getaddrinfo(host, port, &hints, &res)) != 0) {
255
	serv.sin_addr.s_addr = g_gate_str2ip(host);
294
		g_gate_log(LOG_DEBUG, "%s: %s (%s).", gai_strerror(error),
256
	if (serv.sin_addr.s_addr == INADDR_NONE) {
295
		    host, port);
257
		g_gate_log(LOG_DEBUG, "Invalid IP/host name: %s.", host);
258
		return (-1);
296
		return (-1);
259
	}
297
	} else {
260
	serv.sin_port = htons(port);
298
		p = res;
261
	sfd = socket(AF_INET, SOCK_STREAM, 0);
299
		while (p) {
262
	if (sfd == -1) {
300
			sfd = socket(p->ai_family, p->ai_socktype, ai_protocol);
263
		g_gate_log(LOG_DEBUG, "Cannot open socket: %s.",
301
			if (sfd == -1) {
264
		    strerror(errno));
302
				g_gate_log(LOG_DEBUG, "Cannot open socket: %s.",
265
		return (-1);
303
				    strerror(errno));
266
	}
304
				freeaddrinfo(res);
305
				return (-1);
306
			}
267
307
268
	g_gate_socket_settings(sfd);
308
			g_gate_socket_settings(sfd);
269
309
270
	if (connect(sfd, (struct sockaddr *)&serv, sizeof(serv)) == -1) {
310
			if (connect(sfd, p->ai_addr, p->ai_addrlen) == 0)
271
		g_gate_log(LOG_DEBUG, "Cannot connect to server: %s.",
311
				break;
272
		    strerror(errno));
312
273
		close(sfd);
313
			/* Non-critical error, try next address */
314
		        g_gate_log(LOG_DEBUG, "Cannot connect to server: %s.",
315
				strerror(errno));
316
			close(sfd);
317
			sfd = -1;
318
319
			p = p->ai_next;
320
		}
321
	}
322
	freeaddrinfo(res);
323
324
	if (sfd == -1) {
325
		g_gate_log(LOG_DEBUG, "Invalid IP/host name or port: %s (%s).",
326
		    host, port);
274
		return (-1);
327
		return (-1);
275
	}
328
	}
276
329
277
	g_gate_log(LOG_INFO, "Connected to the server: %s:%d.", host, port);
330
	g_gate_log(LOG_INFO, "Connected to the server: %s (%s).", host, port);
278
331
279
	/*
332
	/*
280
	 * Create and send version packet.
333
	 * Create and send version packet.
Lines 356-363 Link Here
356
static void
409
static void
357
mydaemon(void)
410
mydaemon(void)
358
{
411
{
359
412
	if (foreground || g_gate_verbose > 0)
360
	if (g_gate_verbose > 0)
361
		return;
413
		return;
362
	if (daemon(0, 0) == 0)
414
	if (daemon(0, 0) == 0)
363
		return;
415
		return;
Lines 420-425 Link Here
420
	struct g_gate_ctl_cancel ggioc;
472
	struct g_gate_ctl_cancel ggioc;
421
473
422
	signal(SIGUSR1, signop);
474
	signal(SIGUSR1, signop);
475
	signal(SIGINFO, summaryx);
423
	for (;;) {
476
	for (;;) {
424
		g_gatec_start();
477
		g_gatec_start();
425
		g_gate_log(LOG_NOTICE, "Disconnected [%s %s]. Connecting...",
478
		g_gate_log(LOG_NOTICE, "Disconnected [%s %s]. Connecting...",
Lines 454-460 Link Here
454
	ggioc.gctl_maxcount = queue_size;
507
	ggioc.gctl_maxcount = queue_size;
455
	ggioc.gctl_timeout = timeout;
508
	ggioc.gctl_timeout = timeout;
456
	ggioc.gctl_unit = unit;
509
	ggioc.gctl_unit = unit;
457
	snprintf(ggioc.gctl_info, sizeof(ggioc.gctl_info), "%s:%u %s", host,
510
	snprintf(ggioc.gctl_info, sizeof(ggioc.gctl_info), "%s (%s) %s", host,
458
	    port, path);
511
	    port, path);
459
	g_gate_ioctl(G_GATE_CMD_CREATE, &ggioc);
512
	g_gate_ioctl(G_GATE_CMD_CREATE, &ggioc);
460
	if (unit == -1) {
513
	if (unit == -1) {
Lines 487-492 Link Here
487
int
540
int
488
main(int argc, char *argv[])
541
main(int argc, char *argv[])
489
{
542
{
543
	struct protoent *pent;
544
	hints.ai_family = PF_UNSPEC;
545
	hints.ai_socktype = SOCK_STREAM;
490
546
491
	if (argc < 2)
547
	if (argc < 2)
492
		usage();
548
		usage();
Lines 505-517 Link Here
505
	for (;;) {
561
	for (;;) {
506
		int ch;
562
		int ch;
507
563
508
		ch = getopt(argc, argv, "fno:p:q:R:S:s:t:u:v");
564
		ch = getopt(argc, argv, "fno:p:q:R:S:s:t:u:vF:P:");
509
		if (ch == -1)
565
		if (ch == -1)
510
			break;
566
			break;
511
		switch (ch) {
567
		switch (ch) {
512
		case 'f':
568
		case 'f':
569
#if 0
513
			if (action != DESTROY)
570
			if (action != DESTROY)
514
				usage();
571
				usage();
572
#else
573
			if (action != DESTROY)
574
				foreground = 1;
575
			else
576
#endif
515
			force = 1;
577
			force = 1;
516
			break;
578
			break;
517
		case 'n':
579
		case 'n':
Lines 519-524 Link Here
519
				usage();
581
				usage();
520
			nagle = 0;
582
			nagle = 0;
521
			break;
583
			break;
584
		case 'F':
585
			switch (*optarg) {
586
			case '4':
587
				hints.ai_family = PF_INET;
588
				break;
589
			case '6':
590
				hints.ai_family = PF_INET6;
591
				break;
592
			case '0':
593
				hints.ai_family = PF_UNSPEC;
594
				break;
595
			default:
596
				usage();
597
			}
598
			break;
599
		case 'P':
600
			if (optarg && (pent = getprotobyname(optarg)))
601
				ai_protocol = pent->p_proto;
602
			else {
603
				ai_protocol = 0;
604
				/*
605
				errx(EXIT_FAILURE,
606
				    "protocol %s does not exist.", optarg);
607
				*/
608
			}
609
			break;
610
		case '4':
611
			hints.ai_family = PF_INET;
612
			break;
613
		case '6':
614
			hints.ai_family = PF_INET6;
615
			break;
616
		case 'x':
617
			nagle = 0;
618
			hints.ai_family = PF_INET;
619
			ai_protocol = IPPROTO_SCTP;
620
			break;
522
		case 'o':
621
		case 'o':
523
			if (action != CREATE && action != RESCUE)
622
			if (action != CREATE && action != RESCUE)
524
				usage();
623
				usage();
Lines 537-545 Link Here
537
			if (action != CREATE && action != RESCUE)
636
			if (action != CREATE && action != RESCUE)
538
				usage();
637
				usage();
539
			errno = 0;
638
			errno = 0;
540
			port = strtoul(optarg, NULL, 10);
639
			port = optarg;
541
			if (port == 0 && errno != 0)
542
				errx(EXIT_FAILURE, "Invalid port.");
543
			break;
640
			break;
544
		case 'q':
641
		case 'q':
545
			if (action != CREATE)
642
			if (action != CREATE)
(-)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.
(-)ggated/ggated.c (-134 / +373 lines)
Lines 43-49 Link Here
43
#include <sys/bio.h>
43
#include <sys/bio.h>
44
#include <netinet/in.h>
44
#include <netinet/in.h>
45
#include <netinet/tcp.h>
45
#include <netinet/tcp.h>
46
#include <netinet/sctp.h>
46
#include <arpa/inet.h>
47
#include <arpa/inet.h>
48
#include <netdb.h>
47
#include <signal.h>
49
#include <signal.h>
48
#include <assert.h>
50
#include <assert.h>
49
#include <err.h>
51
#include <err.h>
Lines 68-74 Link Here
68
	time_t		 c_birthtime;
70
	time_t		 c_birthtime;
69
	char		*c_path;
71
	char		*c_path;
70
	uint64_t	 c_token;
72
	uint64_t	 c_token;
71
	in_addr_t	 c_srcip;
73
	struct sockaddr_storage c_srcaddr;
74
	uint64_t	 c_send_seq;
75
	uint64_t	 c_recv_seq;
72
	LIST_ENTRY(ggd_connection) c_next;
76
	LIST_ENTRY(ggd_connection) c_next;
73
};
77
};
74
78
Lines 80-98 Link Here
80
#define	r_cmd		r_hdr.gh_cmd
84
#define	r_cmd		r_hdr.gh_cmd
81
#define	r_offset	r_hdr.gh_offset
85
#define	r_offset	r_hdr.gh_offset
82
#define	r_length	r_hdr.gh_length
86
#define	r_length	r_hdr.gh_length
87
#define	r_seq		r_hdr.gh_seq
83
#define	r_error		r_hdr.gh_error
88
#define	r_error		r_hdr.gh_error
84
89
85
struct ggd_export {
90
struct ggd_export {
86
	char		*e_path;	/* path to device/file */
91
	char		        *e_path;	/* path to device/file */
87
	in_addr_t	 e_ip;		/* remote IP address */
92
	struct sockaddr_storage	 e_addr;	/* remote IP address */
88
	in_addr_t	 e_mask;	/* IP mask */
93
	struct sockaddr_storage	 e_mask;	/* IP mask */
89
	unsigned	 e_flags;	/* flags (RO/RW) */
94
	unsigned		 e_flags;	/* flags (RO/RW) */
90
	SLIST_ENTRY(ggd_export) e_next;
95
	SLIST_ENTRY(ggd_export)	 e_next;
96
};
97
98
struct ggd_listen {
99
	const char			*l_name;   /* host name / address */
100
	struct sockaddr_storage		 l_addr;   /* bind address & port */
101
	int				 l_fd;	   /* socket */
102
	SLIST_ENTRY(ggd_listen)		 l_next;
91
};
103
};
92
104
93
static const char *exports_file = GGATED_EXPORT_FILE;
105
static const char *exports_file = GGATED_EXPORT_FILE;
94
static int got_sighup = 0;
106
static int got_sighup = 0;
95
in_addr_t bindaddr;
107
static int ai_protocol = 0;
108
struct addrinfo hints;
96
109
97
static TAILQ_HEAD(, ggd_request) inqueue = TAILQ_HEAD_INITIALIZER(inqueue);
110
static TAILQ_HEAD(, ggd_request) inqueue = TAILQ_HEAD_INITIALIZER(inqueue);
98
static TAILQ_HEAD(, ggd_request) outqueue = TAILQ_HEAD_INITIALIZER(outqueue);
111
static TAILQ_HEAD(, ggd_request) outqueue = TAILQ_HEAD_INITIALIZER(outqueue);
Lines 110-185 Link Here
110
usage(void)
123
usage(void)
111
{
124
{
112
125
113
	fprintf(stderr, "usage: %s [-nv] [-a address] [-p port] [-R rcvbuf] "
126
	fprintf(stderr, "usage: %s [-fnv] [-a address] [-p port] [-R rcvbuf] "
114
	    "[-S sndbuf] [exports file]\n", getprogname());
127
	    "[-S sndbuf] [exports file]\n", getprogname());
115
	exit(EXIT_FAILURE);
128
	exit(EXIT_FAILURE);
116
}
129
}
117
130
118
static char *
131
static void
119
ip2str(in_addr_t ip)
132
summary(void)
133
{
134
	struct ggd_connection *conn, *tconn;
135
136
        char buf[1024];
137
138
	/* Use snprintf(3) so that we don't reenter stdio(3). */
139
	LIST_FOREACH_SAFE(conn, &connections, c_next, tconn) {
140
		snprintf(buf, sizeof(buf),
141
			"path %s\n"
142
			"send_seq %llu\n"
143
			"recv_seq %llu\n"
144
			"",
145
			conn->c_path,
146
			conn->c_send_seq, conn->c_recv_seq);
147
		write(STDERR_FILENO, buf, strlen(buf));
148
	}
149
}
150
151
static void
152
summaryx(int notused __unused)
120
{
153
{
121
	static char sip[16];
154
	int save_errno = errno;
122
155
123
	snprintf(sip, sizeof(sip), "%u.%u.%u.%u",
156
	summary();
124
	    ((ip >> 24) & 0xff),
157
	errno = save_errno;
125
	    ((ip >> 16) & 0xff),
126
	    ((ip >> 8) & 0xff),
127
	    (ip & 0xff));
128
	return (sip);
129
}
158
}
130
159
131
static in_addr_t
160
static const char *
132
countmask(unsigned m)
161
ip2str(struct sockaddr *addr)
133
{
162
{
134
	in_addr_t mask;
163
	static char sip[64];
135
164
136
	if (m == 0) {
165
	if (getnameinfo(addr, addr->sa_len, sip, sizeof(sip),
137
		mask = 0x0;
166
	    NULL, 0, NI_NUMERICHOST) == 0)
138
	} else {
167
		return (sip);
139
		mask = 1 << (32 - m);
168
140
		mask--;
169
	return ("Unknown");
141
		mask = ~mask;
170
}
171
172
static struct sockaddr_storage
173
countmask(struct sockaddr* addr, int mask)	/* also normalizes addr */
174
{
175
	struct sockaddr_storage ss;
176
	int i, alen;
177
	unsigned char *mp, *ap;
178
179
	bzero(&ss, sizeof(ss));
180
	ss.ss_family = addr->sa_family;
181
	ss.ss_len = addr->sa_len;
182
183
	switch (addr->sa_family) {
184
		case AF_INET:
185
			alen = 4;	/* 32 bits */
186
			ap = (unsigned char*)&((struct sockaddr_in*)addr)->sin_addr.s_addr;
187
			mp = (unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr;
188
			break;
189
		case AF_INET6:
190
			alen = 16;	/* 128 bits */
191
			ap = (unsigned char*)&((struct sockaddr_in6*)addr)->sin6_addr.s6_addr;
192
			mp = (unsigned char*)&((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr;
193
			break;
194
		default:
195
			g_gate_xlog("Unknown address family in countmask");
196
			return ss;
197
	}
198
199
	i = 0;
200
	while (mask > 0 && i < alen) {
201
		if (mask < 8) {
202
			mp[i] = ~(0xff >> mask);
203
			ap[i] &= mp[i];
204
		} else
205
			mp[i] = 0xff;
206
		i++;
207
		mask -= 8;
208
	}
209
	while (i < alen) {		/* zero out remaining bits of addr */
210
		ap[i] = 0;
211
		i++;
142
	}
212
	}
143
	return (mask);
213
214
	return (ss);
144
}
215
}
145
216
146
static void
217
static void
147
line_parse(char *line, unsigned lineno)
218
line_parse(char *line, unsigned lineno)
148
{
219
{
149
	struct ggd_export *ex;
220
	struct ggd_export *ex;
150
	char *word, *path, *sflags;
221
	char *pmask, *word, *path, *sflags;
151
	unsigned flags, i, vmask;
222
	unsigned flags, i;
152
	in_addr_t ip, mask;
223
	int vmask;
224
	struct addrinfo *res, *p;
153
225
154
	ip = mask = flags = vmask = 0;
226
	flags = vmask = 0;
155
	path = NULL;
227
	path = NULL;
156
	sflags = NULL;
228
	sflags = NULL;
229
	pmask = NULL;
157
230
158
	for (i = 0, word = strtok(line, " \t"); word != NULL;
231
	for (i = 0, word = strtok(line, " \t"); word != NULL;
159
	    i++, word = strtok(NULL, " \t")) {
232
	    i++, word = strtok(NULL, " \t")) {
160
		switch (i) {
233
		switch (i) {
161
		case 0: /* IP address or host name */
234
		case 0: /* IP address or host name */
162
			ip = g_gate_str2ip(strsep(&word, "/"));
235
			// bzero(&hints, sizeof(hints));
163
			if (ip == INADDR_NONE) {
236
			// hints.ai_family = PF_UNSPEC;
237
			// hints.ai_socktype = SOCKET_STREAM;
238
			if (getaddrinfo(strsep(&word, "/"), NULL, &hints,
239
			    &res) != 0)
164
				g_gate_xlog("Invalid IP/host name at line %u.",
240
				g_gate_xlog("Invalid IP/host name at line %u.",
165
				    lineno);
241
				    lineno);
166
			}
242
			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;
243
			break;
184
		case 1:	/* flags */
244
		case 1:	/* flags */
185
			if (strcasecmp("rd", word) == 0 ||
245
			if (strcasecmp("rd", word) == 0 ||
Lines 209-230 Link Here
209
	if (i != 3)
269
	if (i != 3)
210
		g_gate_xlog("Too few arguments at line %u.", lineno);
270
		g_gate_xlog("Too few arguments at line %u.", lineno);
211
271
212
	ex = malloc(sizeof(*ex));
272
	p = res;
213
	if (ex == NULL)
273
	while (p) {
214
		g_gate_xlog("No enough memory.");
274
		ex = malloc(sizeof(*ex));
215
	ex->e_path = strdup(path);
275
		if (ex == NULL)
216
	if (ex->e_path == NULL)
276
			g_gate_xlog("Not enough memory.");
217
		g_gate_xlog("No enough memory.");
277
		ex->e_path = strdup(path);
218
278
		if (ex->e_path == NULL)
219
	/* Made 'and' here. */
279
			g_gate_xlog("Not enough memory.");
220
	ex->e_ip = (ip & mask);
280
221
	ex->e_mask = mask;
281
		if (pmask == NULL && p->ai_family == AF_INET6)
222
	ex->e_flags = flags;
282
			vmask = 128;
283
		else if (pmask == NULL)
284
			vmask = 32;
285
		else {
286
			errno = 0;
287
			vmask = strtoul(pmask, NULL, 10);
288
			if (vmask == 0 && errno != 0) {
289
				g_gate_xlog("Invalid IP mask value at "
290
				    "line %u.", lineno);
291
			}
292
		}
293
294
		if ((vmask > 32 && p->ai_family == AF_INET) ||
295
		    (vmask > 128 && p->ai_family == AF_INET6))
296
			g_gate_xlog("Invalid IP mask value at line %u",
297
			    lineno);
298
299
		memcpy(&ex->e_addr, p->ai_addr, p->ai_addrlen);
300
		ex->e_mask = countmask((struct sockaddr*)&ex->e_addr, vmask);
301
		ex->e_flags = flags;
223
302
224
	SLIST_INSERT_HEAD(&exports, ex, e_next);
303
		SLIST_INSERT_HEAD(&exports, ex, e_next);
304
305
		g_gate_log(LOG_DEBUG, "Added %s/%u %s %s to exports list.",
306
		    ip2str((struct sockaddr*)&ex->e_addr), vmask, path, sflags);
307
308
		p = p->ai_next;
309
	}
225
310
226
	g_gate_log(LOG_DEBUG, "Added %s/%u %s %s to exports list.",
311
	freeaddrinfo(res);
227
	    ip2str(ex->e_ip), vmask, path, sflags);
228
}
312
}
229
313
230
static void
314
static void
Lines 302-313 Link Here
302
exports_check(struct ggd_export *ex, struct g_gate_cinit *cinit,
386
exports_check(struct ggd_export *ex, struct g_gate_cinit *cinit,
303
    struct ggd_connection *conn)
387
    struct ggd_connection *conn)
304
{
388
{
305
	char ipmask[32]; /* 32 == strlen("xxx.xxx.xxx.xxx/xxx.xxx.xxx.xxx")+1 */
389
	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;
390
	int error = 0, flags;
307
391
308
	strlcpy(ipmask, ip2str(ex->e_ip), sizeof(ipmask));
392
	strlcpy(ipmask, ip2str((struct sockaddr*)&ex->e_addr), sizeof(ipmask));
309
	strlcat(ipmask, "/", sizeof(ipmask));
393
	strlcat(ipmask, "/", sizeof(ipmask));
310
	strlcat(ipmask, ip2str(ex->e_mask), sizeof(ipmask));
394
	strlcat(ipmask, ip2str((struct sockaddr*)&ex->e_mask), sizeof(ipmask));
311
	if ((cinit->gc_flags & GGATE_FLAG_RDONLY) != 0) {
395
	if ((cinit->gc_flags & GGATE_FLAG_RDONLY) != 0) {
312
		if (ex->e_flags == O_WRONLY) {
396
		if (ex->e_flags == O_WRONLY) {
313
			g_gate_log(LOG_WARNING, "Read-only access requested, "
397
			g_gate_log(LOG_WARNING, "Read-only access requested, "
Lines 355-371 Link Here
355
	return (0);
439
	return (0);
356
}
440
}
357
441
442
static int
443
mask_compare(struct sockaddr *a, struct sockaddr *b, struct sockaddr *m) {
444
	unsigned char *ap, *bp, *mp;
445
	int alen;
446
	if (a->sa_family != m->sa_family || b->sa_family != m->sa_family)
447
		return (0);
448
449
	switch (m->sa_family) {
450
		case AF_INET:
451
			alen = 4;
452
			ap = (unsigned char*)&((struct sockaddr_in*)a)->sin_addr.s_addr;
453
			bp = (unsigned char*)&((struct sockaddr_in*)b)->sin_addr.s_addr;
454
			mp = (unsigned char*)&((struct sockaddr_in*)m)->sin_addr.s_addr;
455
			break;
456
		case AF_INET6:
457
			alen = 16;
458
			ap = (unsigned char*)&((struct sockaddr_in6*)a)->sin6_addr.s6_addr;
459
			bp = (unsigned char*)&((struct sockaddr_in6*)b)->sin6_addr.s6_addr;
460
			mp = (unsigned char*)&((struct sockaddr_in6*)m)->sin6_addr.s6_addr;
461
			break;
462
		default:
463
			return (0);
464
	}
465
466
	while (alen > 0) {
467
		if ((*ap & *mp) != (*bp & *mp))
468
			return (0);
469
		
470
		ap++;
471
		bp++;
472
		mp++;
473
		alen--;
474
	}
475
476
	return (1);
477
}
478
358
static struct ggd_export *
479
static struct ggd_export *
359
exports_find(struct sockaddr *s, struct g_gate_cinit *cinit,
480
exports_find(struct sockaddr *s, struct g_gate_cinit *cinit,
360
    struct ggd_connection *conn)
481
    struct ggd_connection *conn)
361
{
482
{
362
	struct ggd_export *ex;
483
	struct ggd_export *ex;
363
	in_addr_t ip;
364
	int error;
484
	int error;
365
485
366
	ip = htonl(((struct sockaddr_in *)(void *)s)->sin_addr.s_addr);
367
	SLIST_FOREACH(ex, &exports, e_next) {
486
	SLIST_FOREACH(ex, &exports, e_next) {
368
		if ((ip & ex->e_mask) != ex->e_ip) {
487
		if (!mask_compare(s, (struct sockaddr*)&ex->e_addr,
488
				 (struct sockaddr*)&ex->e_mask)) {
369
			g_gate_log(LOG_DEBUG, "exports[%s]: IP mismatch.",
489
			g_gate_log(LOG_DEBUG, "exports[%s]: IP mismatch.",
370
			    ex->e_path);
490
			    ex->e_path);
371
			continue;
491
			continue;
Lines 384-390 Link Here
384
		}
504
		}
385
	}
505
	}
386
	g_gate_log(LOG_WARNING, "Unauthorized connection from: %s.",
506
	g_gate_log(LOG_WARNING, "Unauthorized connection from: %s.",
387
	    ip2str(ip));
507
	    ip2str(s));
388
	errno = EPERM;
508
	errno = EPERM;
389
	return (NULL);
509
	return (NULL);
390
}
510
}
Lines 404-410 Link Here
404
			LIST_REMOVE(conn, c_next);
524
			LIST_REMOVE(conn, c_next);
405
			g_gate_log(LOG_NOTICE,
525
			g_gate_log(LOG_NOTICE,
406
			    "Connection from %s [%s] removed.",
526
			    "Connection from %s [%s] removed.",
407
			    ip2str(conn->c_srcip), conn->c_path);
527
			    ip2str((struct sockaddr*)&conn->c_srcaddr),
528
			    conn->c_path);
408
			close(conn->c_diskfd);
529
			close(conn->c_diskfd);
409
			close(conn->c_sendfd);
530
			close(conn->c_sendfd);
410
			close(conn->c_recvfd);
531
			close(conn->c_recvfd);
Lines 430-436 Link Here
430
connection_new(struct g_gate_cinit *cinit, struct sockaddr *s, int sfd)
551
connection_new(struct g_gate_cinit *cinit, struct sockaddr *s, int sfd)
431
{
552
{
432
	struct ggd_connection *conn;
553
	struct ggd_connection *conn;
433
	in_addr_t ip;
434
554
435
	/*
555
	/*
436
	 * First, look for old connections.
556
	 * First, look for old connections.
Lines 449-456 Link Here
449
		return (NULL);
569
		return (NULL);
450
	}
570
	}
451
	conn->c_token = cinit->gc_token;
571
	conn->c_token = cinit->gc_token;
452
	ip = htonl(((struct sockaddr_in *)(void *)s)->sin_addr.s_addr);
572
	memcpy(&conn->c_srcaddr, s, s->sa_len);
453
	conn->c_srcip = ip;
454
	conn->c_sendfd = conn->c_recvfd = -1;
573
	conn->c_sendfd = conn->c_recvfd = -1;
455
	if ((cinit->gc_flags & GGATE_FLAG_SEND) != 0)
574
	if ((cinit->gc_flags & GGATE_FLAG_SEND) != 0)
456
		conn->c_sendfd = sfd;
575
		conn->c_sendfd = sfd;
Lines 461-467 Link Here
461
	time(&conn->c_birthtime);
580
	time(&conn->c_birthtime);
462
	conn->c_flags = cinit->gc_flags;
581
	conn->c_flags = cinit->gc_flags;
463
	LIST_INSERT_HEAD(&connections, conn, c_next);
582
	LIST_INSERT_HEAD(&connections, conn, c_next);
464
	g_gate_log(LOG_DEBUG, "Connection created [%s, %s].", ip2str(ip),
583
	g_gate_log(LOG_DEBUG, "Connection created [%s, %s].", ip2str(s),
465
	    conn->c_path);
584
	    conn->c_path);
466
	return (conn);
585
	return (conn);
467
}
586
}
Lines 470-482 Link Here
470
connection_add(struct ggd_connection *conn, struct g_gate_cinit *cinit,
589
connection_add(struct ggd_connection *conn, struct g_gate_cinit *cinit,
471
    struct sockaddr *s, int sfd)
590
    struct sockaddr *s, int sfd)
472
{
591
{
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) {
592
	if ((cinit->gc_flags & GGATE_FLAG_SEND) != 0) {
477
		if (conn->c_sendfd != -1) {
593
		if (conn->c_sendfd != -1) {
478
			g_gate_log(LOG_WARNING,
594
			g_gate_log(LOG_WARNING,
479
			    "Send socket already exists [%s, %s].", ip2str(ip),
595
			    "Send socket already exists [%s, %s].", ip2str(s),
480
			    conn->c_path);
596
			    conn->c_path);
481
			return (EEXIST);
597
			return (EEXIST);
482
		}
598
		}
Lines 485-496 Link Here
485
		if (conn->c_recvfd != -1) {
601
		if (conn->c_recvfd != -1) {
486
			g_gate_log(LOG_WARNING,
602
			g_gate_log(LOG_WARNING,
487
			    "Receive socket already exists [%s, %s].",
603
			    "Receive socket already exists [%s, %s].",
488
			    ip2str(ip), conn->c_path);
604
			    ip2str(s), conn->c_path);
489
			return (EEXIST);
605
			return (EEXIST);
490
		}
606
		}
491
		conn->c_recvfd = sfd;
607
		conn->c_recvfd = sfd;
492
	}
608
	}
493
	g_gate_log(LOG_DEBUG, "Connection added [%s, %s].", ip2str(ip),
609
	g_gate_log(LOG_DEBUG, "Connection added [%s, %s].", ip2str(s),
494
	    conn->c_path);
610
	    conn->c_path);
495
	return (0);
611
	return (0);
496
}
612
}
Lines 505-515 Link Here
505
621
506
	LIST_REMOVE(conn, c_next);
622
	LIST_REMOVE(conn, c_next);
507
	g_gate_log(LOG_DEBUG, "Connection removed [%s %s].",
623
	g_gate_log(LOG_DEBUG, "Connection removed [%s %s].",
508
	    ip2str(conn->c_srcip), conn->c_path);
624
	    ip2str((struct sockaddr*)&conn->c_srcaddr), conn->c_path);
509
	if (conn->c_sendfd != -1)
625
	if (conn->c_sendfd != -1)
510
		close(conn->c_sendfd);
626
		close(conn->c_sendfd);
511
	if (conn->c_recvfd != -1)
627
	if (conn->c_recvfd != -1)
512
		close(conn->c_recvfd);
628
		close(conn->c_recvfd);
629
	close(conn->c_diskfd);
513
	free(conn->c_path);
630
	free(conn->c_path);
514
	free(conn);
631
	free(conn);
515
}
632
}
Lines 642-652 Link Here
642
		} else if (data != sizeof(req->r_hdr)) {
759
		} else if (data != sizeof(req->r_hdr)) {
643
			g_gate_xlog("Malformed hdr packet received.");
760
			g_gate_xlog("Malformed hdr packet received.");
644
		}
761
		}
645
		g_gate_log(LOG_DEBUG, "Received hdr packet.");
646
		g_gate_swap2h_hdr(&req->r_hdr);
762
		g_gate_swap2h_hdr(&req->r_hdr);
763
		g_gate_log(LOG_DEBUG, "Received hdr packet (seq=%llu).", req->r_seq);
764
		conn->c_recv_seq = req->r_seq;
647
765
648
		g_gate_log(LOG_DEBUG, "%s: offset=%jd length=%u", __func__,
766
		g_gate_log(LOG_DEBUG, "%s: (offset=%jd length=%u", __func__,
649
		    (intmax_t)req->r_offset, (unsigned)req->r_length);
767
		    req->r_seq, (intmax_t)req->r_offset, (unsigned)req->r_length);
650
768
651
		/*
769
		/*
652
		 * Allocate memory for data.
770
		 * Allocate memory for data.
Lines 657-664 Link Here
657
		 * Receive data to write for WRITE request.
775
		 * Receive data to write for WRITE request.
658
		 */
776
		 */
659
		if (req->r_cmd == GGATE_CMD_WRITE) {
777
		if (req->r_cmd == GGATE_CMD_WRITE) {
660
			g_gate_log(LOG_DEBUG, "Waiting for %u bytes of data...",
778
			g_gate_log(LOG_DEBUG, "Waiting for %u bytes of data (seq=%llu).",
661
			    req->r_length);
779
			    req->r_length, req->r_seq);
662
			data = g_gate_recv(fd, req->r_data, req->r_length,
780
			data = g_gate_recv(fd, req->r_data, req->r_length,
663
			    MSG_WAITALL);
781
			    MSG_WAITALL);
664
			if (data == -1) {
782
			if (data == -1) {
Lines 795-802 Link Here
795
			g_gate_xlog("Error while sending hdr packet: %s.",
913
			g_gate_xlog("Error while sending hdr packet: %s.",
796
			    strerror(errno));
914
			    strerror(errno));
797
		}
915
		}
798
		g_gate_log(LOG_DEBUG, "Sent hdr packet.");
799
		g_gate_swap2h_hdr(&req->r_hdr);
916
		g_gate_swap2h_hdr(&req->r_hdr);
917
		g_gate_log(LOG_DEBUG, "Sent hdr packet (seq=%llu).", req->r_hdr.gh_seq);
918
		conn->c_send_seq = req->r_seq;
800
		if (req->r_data != NULL) {
919
		if (req->r_data != NULL) {
801
			data = g_gate_send(fd, req->r_data, req->r_length, 0);
920
			data = g_gate_send(fd, req->r_data, req->r_length, 0);
802
			if (data != (ssize_t)req->r_length) {
921
			if (data != (ssize_t)req->r_length) {
Lines 815-824 Link Here
815
static void
934
static void
816
log_connection(struct sockaddr *from)
935
log_connection(struct sockaddr *from)
817
{
936
{
818
	in_addr_t ip;
937
	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
}
938
}
823
939
824
static int
940
static int
Lines 940-975 Link Here
940
int
1056
int
941
main(int argc, char *argv[])
1057
main(int argc, char *argv[])
942
{
1058
{
943
	struct sockaddr_in serv;
1059
	SLIST_HEAD(, ggd_listen) listens = SLIST_HEAD_INITIALIZER(&listens);
944
	struct sockaddr from;
1060
	struct ggd_listen *cl, *nl;
1061
	struct addrinfo *res, *p;
1062
	struct sockaddr_storage from;
1063
	struct protoent *pent;
945
	socklen_t fromlen;
1064
	socklen_t fromlen;
946
	int sfd, tmpsfd;
1065
	int maxfd, tmpsfd;
947
	unsigned port;
1066
	fd_set listenfds;
1067
	const char *port;
1068
	int foreground = 0;
1069
1070
	bzero(&hints, sizeof(hints));
1071
	hints.ai_family = PF_UNSPEC; /* Bind to all address families */
1072
	hints.ai_flags = AI_PASSIVE;
1073
	hints.ai_socktype = SOCK_STREAM;
948
1074
949
	bindaddr = htonl(INADDR_ANY);
1075
	port = G_GATE_PORT_STR;
950
	port = G_GATE_PORT;
951
	for (;;) {
1076
	for (;;) {
952
		int ch;
1077
		int ch;
953
1078
954
		ch = getopt(argc, argv, "a:hnp:R:S:v");
1079
		ch = getopt(argc, argv, "a:fhnp:R:S:vF:P:");
955
		if (ch == -1)
1080
		if (ch == -1)
956
			break;
1081
			break;
957
		switch (ch) {
1082
		switch (ch) {
958
		case 'a':
1083
		case 'a':
959
			bindaddr = g_gate_str2ip(optarg);
1084
			nl = malloc(sizeof(*nl));
960
			if (bindaddr == INADDR_NONE) {
1085
			bzero(nl, sizeof(*nl));
1086
			nl->l_name = optarg;
1087
			/* delay resolution until we know port number */
1088
			SLIST_INSERT_HEAD(&listens, nl, l_next);
1089
			break;
1090
		case 'n':
1091
			nagle = 0;
1092
			break;
1093
		case 'F':
1094
			switch (*optarg) {
1095
			case '4':
1096
				hints.ai_family = PF_INET;
1097
				break;
1098
			case '6':
1099
				hints.ai_family = PF_INET6;
1100
				break;
1101
			case '0':
1102
				hints.ai_family = PF_UNSPEC;
1103
				break;
1104
			default:
1105
				usage();
1106
			}
1107
			break;
1108
		case 'P':
1109
			if (optarg && (pent = getprotobyname(optarg)))
1110
				ai_protocol = pent->p_proto;
1111
			else {
1112
				ai_protocol = 0;
1113
				/*
961
				errx(EXIT_FAILURE,
1114
				errx(EXIT_FAILURE,
962
				    "Invalid IP/host name to bind to.");
1115
					"protocol %s does not exist.", optarg);
1116
				*/
963
			}
1117
			}
964
			break;
1118
			break;
965
		case 'n':
1119
		case '4':
1120
			hints.ai_family = PF_INET;
1121
			break;
1122
		case '6':
1123
			hints.ai_family = PF_INET6;
1124
			break;
1125
		case 'x':
1126
			/* "man netstat" shows AF_INET has sctp. */
1127
			hints.ai_family = PF_INET;
1128
			hints.ai_family = PF_INET6; /* test... */
1129
			/* hints.ai_protocol = IPPROTO_SCTP; */
1130
			ai_protocol = IPPROTO_SCTP;
966
			nagle = 0;
1131
			nagle = 0;
967
			break;
1132
			break;
968
		case 'p':
1133
		case 'p':
969
			errno = 0;
1134
			port = optarg;
970
			port = strtoul(optarg, NULL, 10);
971
			if (port == 0 && errno != 0)
972
				errx(EXIT_FAILURE, "Invalid port.");
973
			break;
1135
			break;
974
		case 'R':
1136
		case 'R':
975
			errno = 0;
1137
			errno = 0;
Lines 983-990 Link Here
983
			if (sndbuf == 0 && errno != 0)
1145
			if (sndbuf == 0 && errno != 0)
984
				errx(EXIT_FAILURE, "Invalid sndbuf.");
1146
				errx(EXIT_FAILURE, "Invalid sndbuf.");
985
			break;
1147
			break;
1148
		case 'f':
1149
			foreground = 1;
1150
			break;
986
		case 'v':
1151
		case 'v':
987
			g_gate_verbose++;
1152
			g_gate_verbose++;
1153
			foreground = 1;
988
			break;
1154
			break;
989
		case 'h':
1155
		case 'h':
990
		default:
1156
		default:
Lines 998-1044 Link Here
998
		exports_file = argv[0];
1164
		exports_file = argv[0];
999
	exports_get();
1165
	exports_get();
1000
1166
1001
	if (!g_gate_verbose) {
1167
	if (SLIST_EMPTY(&listens)) {
1168
		if (getaddrinfo(NULL, port, &hints, &res))
1169
			g_gate_xlog("Cannot get passive address: %s",
1170
			    strerror(errno));
1171
1172
		p = res;
1173
		while (p) {
1174
			nl = malloc(sizeof(*nl));
1175
			bzero(nl, sizeof(*nl));
1176
			memcpy(&nl->l_addr, p->ai_addr, p->ai_addrlen);
1177
			SLIST_INSERT_HEAD(&listens, nl, l_next);
1178
			
1179
			p = p->ai_next;
1180
		}
1181
		freeaddrinfo(res);
1182
	} else {
1183
		/* Bind to some specific addresses */
1184
		SLIST_FOREACH(cl, &listens, l_next) {
1185
			if (getaddrinfo(cl->l_name, port, &hints, &res))
1186
				g_gate_xlog("Invalid IP/host name to bind to: "
1187
				    "%s", cl->l_name);
1188
1189
			/* Re-use current list entry for first match, add
1190
			 * new ones after that */
1191
			p = res;
1192
			nl = cl;
1193
			while (p) {
1194
				if (p != res) {
1195
					nl = malloc(sizeof(*nl));
1196
					bzero(nl, sizeof(*nl));
1197
				}
1198
1199
				memcpy(&nl->l_addr, p->ai_addr, p->ai_addrlen);
1200
1201
				if (p != res) {
1202
					SLIST_INSERT_HEAD(&listens, nl, l_next);
1203
				}
1204
				p = p->ai_next;
1205
			}
1206
			freeaddrinfo(res);
1207
		}
1208
	}
1209
1210
	/* Actually create sockets and bind to them */
1211
	maxfd = 0;
1212
	SLIST_FOREACH(cl, &listens, l_next) {
1213
		cl->l_fd = socket(cl->l_addr.ss_family,
1214
			hints.ai_socktype, ai_protocol);
1215
		if (cl->l_fd == -1)
1216
			g_gate_xlog("Cannot open stream socket: %s.",
1217
			    strerror(errno));
1218
		g_gate_socket_settings(cl->l_fd);
1219
1220
		if (bind(cl->l_fd, (struct sockaddr *)&cl->l_addr,
1221
		    cl->l_addr.ss_len) == -1) {
1222
			g_gate_log(LOG_WARNING, "bind(): %s.", strerror(errno));
1223
			continue;
1224
		}
1225
		if (listen(cl->l_fd, 5) == -1)
1226
			g_gate_xlog("listen(): %s.", strerror(errno));
1227
1228
		if (maxfd <= cl->l_fd)
1229
			maxfd = cl->l_fd + 1;
1230
1231
		g_gate_log(LOG_INFO, "Listen on address: %s (%s).",
1232
			ip2str((struct sockaddr *)&cl->l_addr), port);
1233
	}
1234
1235
	signal(SIGINFO, summaryx);
1236
	if (!foreground) {
1002
		/* Run in daemon mode. */
1237
		/* Run in daemon mode. */
1003
		if (daemon(0, 0) == -1)
1238
		if (daemon(0, 0) == -1)
1004
			g_gate_xlog("Cannot daemonize: %s", strerror(errno));
1239
			g_gate_xlog("Cannot daemonize: %s", strerror(errno));
1005
	}
1240
	}
1006
1241
1007
	signal(SIGCHLD, SIG_IGN);
1242
	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);
1243
	signal(SIGHUP, huphandler);
1027
1244
1028
	for (;;) {
1245
	for (;;) {
1029
		fromlen = sizeof(from);
1246
		FD_ZERO(&listenfds);
1030
		tmpsfd = accept(sfd, &from, &fromlen);
1247
		SLIST_FOREACH(cl, &listens, l_next) {
1031
		if (tmpsfd == -1)
1248
			FD_SET(cl->l_fd, &listenfds);
1032
			g_gate_xlog("accept(): %s.", strerror(errno));
1249
		}
1250
1251
		select(maxfd, &listenfds, NULL, NULL, NULL);
1033
1252
1034
		if (got_sighup) {
1253
		if (got_sighup) {
1035
			got_sighup = 0;
1254
			got_sighup = 0;
1036
			exports_get();
1255
			exports_get();
1037
		}
1256
		}
1038
1257
1039
		if (!handshake(&from, tmpsfd))
1258
		SLIST_FOREACH(cl, &listens, l_next) {
1040
			close(tmpsfd);
1259
			if (!FD_ISSET(cl->l_fd, &listenfds))
1260
				continue;
1261
1262
			fromlen = sizeof(from);
1263
			tmpsfd = accept(cl->l_fd, (struct sockaddr*)&from,
1264
			    &fromlen);
1265
1266
			if (tmpsfd == -1) {
1267
				g_gate_log(LOG_WARNING, "accept(): %s.",
1268
				    strerror(errno));
1269
				continue;
1270
			}
1271
1272
			if (!handshake((struct sockaddr*)&from, tmpsfd))
1273
				close(tmpsfd);
1274
		}
1275
	}
1276
	while (!SLIST_EMPTY(&listens)) {
1277
		cl = SLIST_FIRST(&listens);
1278
		close(cl->l_fd);
1279
		SLIST_REMOVE_HEAD(&listens, l_next);
1280
		free(cl);
1041
	}
1281
	}
1042
	close(sfd);
1043
	exit(EXIT_SUCCESS);
1282
	exit(EXIT_SUCCESS);
1044
}
1283
}
(-)shared/ggate.c (-18 lines)
Lines 389-409 Link Here
389
	exit(EXIT_SUCCESS);
389
	exit(EXIT_SUCCESS);
390
}
390
}
391
#endif	/* LIBGEOM */
391
#endif	/* LIBGEOM */
392
393
in_addr_t
394
g_gate_str2ip(const char *str)
395
{
396
	struct hostent *hp;
397
	in_addr_t ip;
398
399
	ip = inet_addr(str);
400
	if (ip != INADDR_NONE) {
401
		/* It is a valid IP address. */
402
		return (ip);
403
	}
404
	/* Check if it is a valid host name. */
405
	hp = gethostbyname(str);
406
	if (hp == NULL)
407
		return (INADDR_NONE);
408
	return (((struct in_addr *)(void *)hp->h_addr)->s_addr);
409
}
(-)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