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

Collapse All | Expand All

(-)a/channels.c (-15 / +2 lines)
Lines 1658-1676 port_open_helper(struct ssh *ssh, Channel *c, char *rtype) Link Here
1658
	free(local_ipaddr);
1658
	free(local_ipaddr);
1659
}
1659
}
1660
1660
1661
static void
1662
channel_set_reuseaddr(int fd)
1663
{
1664
	int on = 1;
1665
1666
	/*
1667
	 * Set socket options.
1668
	 * Allow local port reuse in TIME_WAIT.
1669
	 */
1670
	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
1671
		error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno));
1672
}
1673
1674
void
1661
void
1675
channel_set_x11_refuse_time(struct ssh *ssh, u_int refuse_time)
1662
channel_set_x11_refuse_time(struct ssh *ssh, u_int refuse_time)
1676
{
1663
{
Lines 3337-3343 channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, Link Here
3337
			continue;
3324
			continue;
3338
		}
3325
		}
3339
3326
3340
		channel_set_reuseaddr(sock);
3327
		set_reuseaddr(sock);
3341
3328
3342
		debug("Local forwarding listening on %s port %s.",
3329
		debug("Local forwarding listening on %s port %s.",
3343
		    ntop, strport);
3330
		    ntop, strport);
Lines 4389-4395 x11_create_display_inet(struct ssh *ssh, int x11_display_offset, Link Here
4389
				freeaddrinfo(aitop);
4376
				freeaddrinfo(aitop);
4390
				return -1;
4377
				return -1;
4391
			}
4378
			}
4392
			channel_set_reuseaddr(sock);
4379
			set_reuseaddr(sock);
4393
			if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
4380
			if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
4394
				debug2("%s: bind port %d: %.100s", __func__,
4381
				debug2("%s: bind port %d: %.100s", __func__,
4395
				    port, strerror(errno));
4382
				    port, strerror(errno));
(-)a/misc.c (+38 lines)
Lines 155-160 set_nodelay(int fd) Link Here
155
		error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
155
		error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
156
}
156
}
157
157
158
/* Allow local port reuse in TIME_WAIT */
159
int
160
set_reuseaddr(int fd)
161
{
162
	int on = 1;
163
164
	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
165
		error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno));
166
		return -1;
167
	}
168
	return 0;
169
}
170
171
/* Set routing table */
172
int
173
set_rdomain(int fd, const char *name)
174
{
175
	int rtable;
176
	const char *errstr;
177
178
	if (name == NULL)
179
		return 0; /* default table */
180
181
	rtable = (int)strtonum(name, 0, 255, &errstr);
182
	if (errstr != NULL) {
183
		/* Shouldn't happen */
184
		error("Invalid routing domain \"%s\": %s", name, errstr);
185
		return -1;
186
	}
187
	if (setsockopt(fd, SOL_SOCKET, SO_RTABLE,
188
	    &rtable, sizeof(rtable)) == -1) {
189
		error("Failed to set routing domain %d on fd %d: %s",
190
		    rtable, fd, strerror(errno));
191
		return -1;
192
	}
193
	return 0;
194
}
195
158
/* Characters considered whitespace in strsep calls. */
196
/* Characters considered whitespace in strsep calls. */
159
#define WHITESPACE " \t\r\n"
197
#define WHITESPACE " \t\r\n"
160
#define QUOTE	"\""
198
#define QUOTE	"\""
(-)a/misc.h (+2 lines)
Lines 48-53 char *strdelim(char **); Link Here
48
int	 set_nonblock(int);
48
int	 set_nonblock(int);
49
int	 unset_nonblock(int);
49
int	 unset_nonblock(int);
50
void	 set_nodelay(int);
50
void	 set_nodelay(int);
51
int	 set_reuseaddr(int);
52
int	 set_rdomain(int, const char *);
51
int	 a2port(const char *);
53
int	 a2port(const char *);
52
int	 a2tun(const char *, int *);
54
int	 a2tun(const char *, int *);
53
char	*put_host_port(const char *, u_short);
55
char	*put_host_port(const char *, u_short);
(-)a/servconf.c (-66 / +157 lines)
Lines 14-22 Link Here
14
#include <sys/types.h>
14
#include <sys/types.h>
15
#include <sys/socket.h>
15
#include <sys/socket.h>
16
#include <sys/queue.h>
16
#include <sys/queue.h>
17
#include <sys/sysctl.h>
17
18
18
#include <netinet/in.h>
19
#include <netinet/in.h>
19
#include <netinet/ip.h>
20
#include <netinet/ip.h>
21
#include <net/route.h>
20
22
21
#include <ctype.h>
23
#include <ctype.h>
22
#include <netdb.h>
24
#include <netdb.h>
Lines 53-60 Link Here
53
#include "myproposal.h"
55
#include "myproposal.h"
54
#include "digest.h"
56
#include "digest.h"
55
57
56
static void add_listen_addr(ServerOptions *, char *, int);
58
static void add_listen_addr(ServerOptions *, const char *,
57
static void add_one_listen_addr(ServerOptions *, char *, int);
59
    const char *, int);
60
static void add_one_listen_addr(ServerOptions *, const char *,
61
    const char *, int);
58
62
59
/* Use of privilege separation or not */
63
/* Use of privilege separation or not */
60
extern int use_privsep;
64
extern int use_privsep;
Lines 71-76 initialize_server_options(ServerOptions *options) Link Here
71
	options->queued_listen_addrs = NULL;
75
	options->queued_listen_addrs = NULL;
72
	options->num_queued_listens = 0;
76
	options->num_queued_listens = 0;
73
	options->listen_addrs = NULL;
77
	options->listen_addrs = NULL;
78
	options->num_listen_addrs = 0;
74
	options->address_family = -1;
79
	options->address_family = -1;
75
	options->num_host_key_files = 0;
80
	options->num_host_key_files = 0;
76
	options->num_host_cert_files = 0;
81
	options->num_host_cert_files = 0;
Lines 235-241 fill_default_server_options(ServerOptions *options) Link Here
235
	if (options->address_family == -1)
240
	if (options->address_family == -1)
236
		options->address_family = AF_UNSPEC;
241
		options->address_family = AF_UNSPEC;
237
	if (options->listen_addrs == NULL)
242
	if (options->listen_addrs == NULL)
238
		add_listen_addr(options, NULL, 0);
243
		add_listen_addr(options, NULL, NULL, 0);
239
	if (options->pid_file == NULL)
244
	if (options->pid_file == NULL)
240
		options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
245
		options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
241
	if (options->login_grace_time == -1)
246
	if (options->login_grace_time == -1)
Lines 612-634 derelativise_path(const char *path) Link Here
612
}
617
}
613
618
614
static void
619
static void
615
add_listen_addr(ServerOptions *options, char *addr, int port)
620
add_listen_addr(ServerOptions *options, const char *addr,
621
    const char *rdomain, int port)
616
{
622
{
617
	u_int i;
623
	u_int i;
618
624
619
	if (port == 0)
625
	if (port > 0)
620
		for (i = 0; i < options->num_ports; i++)
626
		add_one_listen_addr(options, addr, rdomain, port);
621
			add_one_listen_addr(options, addr, options->ports[i]);
627
	else {
622
	else
628
		for (i = 0; i < options->num_ports; i++) {
623
		add_one_listen_addr(options, addr, port);
629
			add_one_listen_addr(options, addr, rdomain,
630
			    options->ports[i]);
631
		}
632
	}
624
}
633
}
625
634
626
static void
635
static void
627
add_one_listen_addr(ServerOptions *options, char *addr, int port)
636
add_one_listen_addr(ServerOptions *options, const char *addr,
637
    const char *rdomain, int port)
628
{
638
{
629
	struct addrinfo hints, *ai, *aitop;
639
	struct addrinfo hints, *ai, *aitop;
630
	char strport[NI_MAXSERV];
640
	char strport[NI_MAXSERV];
631
	int gaierr;
641
	int gaierr;
642
	u_int i;
643
644
	/* Find listen_addrs entry for this rdomain */
645
	for (i = 0; i < options->num_listen_addrs; i++) {
646
		if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
647
			break;
648
		if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
649
			continue;
650
		if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
651
			break;
652
	}
653
	if (i >= options->num_listen_addrs) {
654
		/* No entry for this rdomain; allocate one */
655
		if (i >= INT_MAX)
656
			fatal("%s: too many listen addresses", __func__);
657
		options->listen_addrs = xrecallocarray(options->listen_addrs,
658
		    options->num_listen_addrs, options->num_listen_addrs + 1,
659
		    sizeof(*options->listen_addrs));
660
		i = options->num_listen_addrs++;
661
		if (rdomain != NULL)
662
			options->listen_addrs[i].rdomain = xstrdup(rdomain);
663
	}
664
	/* options->listen_addrs[i] points to the addresses for this rdomain */
632
665
633
	memset(&hints, 0, sizeof(hints));
666
	memset(&hints, 0, sizeof(hints));
634
	hints.ai_family = options->address_family;
667
	hints.ai_family = options->address_family;
Lines 641-648 add_one_listen_addr(ServerOptions *options, char *addr, int port) Link Here
641
		    ssh_gai_strerror(gaierr));
674
		    ssh_gai_strerror(gaierr));
642
	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
675
	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
643
		;
676
		;
644
	ai->ai_next = options->listen_addrs;
677
	ai->ai_next = options->listen_addrs[i].addrs;
645
	options->listen_addrs = aitop;
678
	options->listen_addrs[i].addrs = aitop;
679
}
680
681
/* Returns nonzero if the routing domain name is valid */
682
static int
683
valid_rdomain(const char *name)
684
{
685
	const char *errstr;
686
	long long num;
687
	struct rt_tableinfo info;
688
	int mib[6];
689
	size_t miblen = sizeof(mib);
690
691
	if (name == NULL)
692
		return 1;
693
694
	num = strtonum(name, 0, 255, &errstr);
695
	if (errstr != NULL)
696
		return 0;
697
698
	/* Check whether the table actually exists */
699
	memset(mib, 0, sizeof(mib));
700
	mib[0] = CTL_NET;
701
	mib[1] = PF_ROUTE;
702
	mib[4] = NET_RT_TABLE;
703
	mib[5] = (int)num;
704
	if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
705
		return 0;
706
707
	return 1;
646
}
708
}
647
709
648
/*
710
/*
Lines 650-667 add_one_listen_addr(ServerOptions *options, char *addr, int port) Link Here
650
 * and AddressFamily options.
712
 * and AddressFamily options.
651
 */
713
 */
652
static void
714
static void
653
queue_listen_addr(ServerOptions *options, char *addr, int port)
715
queue_listen_addr(ServerOptions *options, const char *addr,
716
    const char *rdomain, int port)
654
{
717
{
655
	options->queued_listen_addrs = xreallocarray(
718
	struct queued_listenaddr *qla;
656
	    options->queued_listen_addrs, options->num_queued_listens + 1,
719
657
	    sizeof(addr));
720
	options->queued_listen_addrs = xrecallocarray(
658
	options->queued_listen_ports = xreallocarray(
721
	    options->queued_listen_addrs,
659
	    options->queued_listen_ports, options->num_queued_listens + 1,
722
	    options->num_queued_listens, options->num_queued_listens + 1,
660
	    sizeof(port));
723
	    sizeof(*options->queued_listen_addrs));
661
	options->queued_listen_addrs[options->num_queued_listens] =
724
	qla = &options->queued_listen_addrs[options->num_queued_listens++];
662
	    xstrdup(addr);
725
	qla->addr = xstrdup(addr);
663
	options->queued_listen_ports[options->num_queued_listens] = port;
726
	qla->port = port;
664
	options->num_queued_listens++;
727
	qla->rdomain = xstrdup(rdomain);
665
}
728
}
666
729
667
/*
730
/*
Lines 671-676 static void Link Here
671
process_queued_listen_addrs(ServerOptions *options)
734
process_queued_listen_addrs(ServerOptions *options)
672
{
735
{
673
	u_int i;
736
	u_int i;
737
	struct queued_listenaddr *qla;
674
738
675
	if (options->num_ports == 0)
739
	if (options->num_ports == 0)
676
		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
740
		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
Lines 678-692 process_queued_listen_addrs(ServerOptions *options) Link Here
678
		options->address_family = AF_UNSPEC;
742
		options->address_family = AF_UNSPEC;
679
743
680
	for (i = 0; i < options->num_queued_listens; i++) {
744
	for (i = 0; i < options->num_queued_listens; i++) {
681
		add_listen_addr(options, options->queued_listen_addrs[i],
745
		qla = &options->queued_listen_addrs[i];
682
		    options->queued_listen_ports[i]);
746
		add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
683
		free(options->queued_listen_addrs[i]);
747
		free(qla->addr);
684
		options->queued_listen_addrs[i] = NULL;
748
		free(qla->rdomain);
685
	}
749
	}
686
	free(options->queued_listen_addrs);
750
	free(options->queued_listen_addrs);
687
	options->queued_listen_addrs = NULL;
751
	options->queued_listen_addrs = NULL;
688
	free(options->queued_listen_ports);
689
	options->queued_listen_ports = NULL;
690
	options->num_queued_listens = 0;
752
	options->num_queued_listens = 0;
691
}
753
}
692
754
Lines 1075-1094 process_server_config_line(ServerOptions *options, char *line, Link Here
1075
		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
1137
		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
1076
		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1138
		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1077
		    && strchr(p+1, ':') != NULL) {
1139
		    && strchr(p+1, ':') != NULL) {
1078
			queue_listen_addr(options, arg, 0);
1079
			break;
1080
		}
1081
		p = hpdelim(&arg);
1082
		if (p == NULL)
1083
			fatal("%s line %d: bad address:port usage",
1084
			    filename, linenum);
1085
		p = cleanhostname(p);
1086
		if (arg == NULL)
1087
			port = 0;
1140
			port = 0;
1088
		else if ((port = a2port(arg)) <= 0)
1141
			p = arg;
1089
			fatal("%s line %d: bad port number", filename, linenum);
1142
		} else {
1143
			p = hpdelim(&arg);
1144
			if (p == NULL)
1145
				fatal("%s line %d: bad address:port usage",
1146
				    filename, linenum);
1147
			p = cleanhostname(p);
1148
			if (arg == NULL)
1149
				port = 0;
1150
			else if ((port = a2port(arg)) <= 0)
1151
				fatal("%s line %d: bad port number",
1152
				    filename, linenum);
1153
		}
1154
		/* Optional routing table */
1155
		arg2 = NULL;
1156
		if ((arg = strdelim(&cp)) != NULL) {
1157
			if (strcmp(arg, "rdomain") != 0 ||
1158
			    (arg2 = strdelim(&cp)) == NULL)
1159
				fatal("%s line %d: bad ListenAddress syntax",
1160
				    filename, linenum);
1161
			if (!valid_rdomain(arg2))
1162
				fatal("%s line %d: bad routing domain",
1163
				    filename, linenum);
1164
		}
1090
1165
1091
		queue_listen_addr(options, p, port);
1166
		queue_listen_addr(options, p, arg2, port);
1092
1167
1093
		break;
1168
		break;
1094
1169
Lines 2199-2243 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals) Link Here
2199
	printf("\n");
2274
	printf("\n");
2200
}
2275
}
2201
2276
2202
void
2277
static char *
2203
dump_config(ServerOptions *o)
2278
format_listen_addrs(struct listenaddr *la)
2204
{
2279
{
2205
	u_int i;
2280
	int r;
2206
	int ret;
2207
	struct addrinfo *ai;
2281
	struct addrinfo *ai;
2208
	char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
2282
	char addr[NI_MAXHOST], port[NI_MAXSERV];
2209
	char *laddr1 = xstrdup(""), *laddr2 = NULL;
2283
	char *laddr1 = xstrdup(""), *laddr2 = NULL;
2210
2284
2211
	/* these are usually at the top of the config */
2212
	for (i = 0; i < o->num_ports; i++)
2213
		printf("port %d\n", o->ports[i]);
2214
	dump_cfg_fmtint(sAddressFamily, o->address_family);
2215
2216
	/*
2285
	/*
2217
	 * ListenAddress must be after Port.  add_one_listen_addr pushes
2286
	 * ListenAddress must be after Port.  add_one_listen_addr pushes
2218
	 * addresses onto a stack, so to maintain ordering we need to
2287
	 * addresses onto a stack, so to maintain ordering we need to
2219
	 * print these in reverse order.
2288
	 * print these in reverse order.
2220
	 */
2289
	 */
2221
	for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
2290
	for (ai = la->addrs; ai; ai = ai->ai_next) {
2222
		if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2291
		if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2223
		    sizeof(addr), port, sizeof(port),
2292
		    sizeof(addr), port, sizeof(port),
2224
		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2293
		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2225
			error("getnameinfo failed: %.100s",
2294
			error("getnameinfo: %.100s", ssh_gai_strerror(r));
2226
			    (ret != EAI_SYSTEM) ? gai_strerror(ret) :
2295
			continue;
2227
			    strerror(errno));
2296
		}
2297
		laddr2 = laddr1;
2298
		if (ai->ai_family == AF_INET6) {
2299
			xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
2300
			    addr, port,
2301
			    la->rdomain == NULL ? "" : " rdomain ",
2302
			    la->rdomain == NULL ? "" : la->rdomain,
2303
			    laddr2);
2228
		} else {
2304
		} else {
2229
			laddr2 = laddr1;
2305
			xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
2230
			if (ai->ai_family == AF_INET6)
2306
			    addr, port,
2231
				xasprintf(&laddr1, "listenaddress [%s]:%s\n%s",
2307
			    la->rdomain == NULL ? "" : " rdomain ",
2232
				    addr, port, laddr2);
2308
			    la->rdomain == NULL ? "" : la->rdomain,
2233
			else
2309
			    laddr2);
2234
				xasprintf(&laddr1, "listenaddress %s:%s\n%s",
2235
				    addr, port, laddr2);
2236
			free(laddr2);
2237
		}
2310
		}
2311
		free(laddr2);
2312
	}
2313
	return laddr1;
2314
}
2315
2316
void
2317
dump_config(ServerOptions *o)
2318
{
2319
	char *s;
2320
	u_int i;
2321
2322
	/* these are usually at the top of the config */
2323
	for (i = 0; i < o->num_ports; i++)
2324
		printf("port %d\n", o->ports[i]);
2325
	dump_cfg_fmtint(sAddressFamily, o->address_family);
2326
2327
	for (i = 0; i < o->num_listen_addrs; i++) {
2328
		s = format_listen_addrs(&o->listen_addrs[i]);
2329
		printf("%s", s);
2330
		free(s);
2238
	}
2331
	}
2239
	printf("%s", laddr1);
2240
	free(laddr1);
2241
2332
2242
	/* integer arguments */
2333
	/* integer arguments */
2243
	dump_cfg_int(sLoginGraceTime, o->login_grace_time);
2334
	dump_cfg_int(sLoginGraceTime, o->login_grace_time);
(-)a/servconf.h (-3 / +20 lines)
Lines 51-64 Link Here
51
struct ssh;
51
struct ssh;
52
struct fwd_perm_list;
52
struct fwd_perm_list;
53
53
54
/*
55
 * Used to store addresses from ListenAddr directives. These may be
56
 * incomplete, as they may specify addresses that need to be merged
57
 * with any ports requested by ListenPort.
58
 */
59
struct queued_listenaddr {
60
	char *addr;
61
	int port; /* <=0 if unspecified */
62
	char *rdomain;
63
};
64
65
/* Resolved listen addresses, grouped by optional routing domain */
66
struct listenaddr {
67
	char *rdomain;
68
	struct addrinfo *addrs;
69
};
70
54
typedef struct {
71
typedef struct {
55
	u_int	num_ports;
72
	u_int	num_ports;
56
	u_int	ports_from_cmdline;
73
	u_int	ports_from_cmdline;
57
	int	ports[MAX_PORTS];	/* Port number to listen on. */
74
	int	ports[MAX_PORTS];	/* Port number to listen on. */
75
	struct queued_listenaddr *queued_listen_addrs;
58
	u_int	num_queued_listens;
76
	u_int	num_queued_listens;
59
	char   **queued_listen_addrs;
77
	struct listenaddr *listen_addrs;
60
	int    *queued_listen_ports;
78
	u_int	num_listen_addrs;
61
	struct addrinfo *listen_addrs;	/* Addresses for server to listen. */
62
	int	address_family;		/* Address family used by the server. */
79
	int	address_family;		/* Address family used by the server. */
63
80
64
	char   **host_key_files;	/* Files containing host keys. */
81
	char   **host_key_files;	/* Files containing host keys. */
(-)a/sshd.c (-13 / +31 lines)
Lines 962-974 server_accept_inetd(int *sock_in, int *sock_out) Link Here
962
 * Listen for TCP connections
962
 * Listen for TCP connections
963
 */
963
 */
964
static void
964
static void
965
server_listen(void)
965
listen_on_addrs(struct listenaddr *la)
966
{
966
{
967
	int ret, listen_sock, on = 1;
967
	int ret, listen_sock;
968
	struct addrinfo *ai;
968
	struct addrinfo *ai;
969
	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
969
	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
970
970
971
	for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
971
	for (ai = la->addrs; ai; ai = ai->ai_next) {
972
		if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
972
		if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
973
			continue;
973
			continue;
974
		if (num_listen_socks >= MAX_LISTEN_SOCKS)
974
		if (num_listen_socks >= MAX_LISTEN_SOCKS)
Lines 998-1010 server_listen(void) Link Here
998
			close(listen_sock);
998
			close(listen_sock);
999
			continue;
999
			continue;
1000
		}
1000
		}
1001
		/*
1001
		/* Socket options */
1002
		 * Set socket options.
1002
		set_reuseaddr(listen_sock);
1003
		 * Allow local port reuse in TIME_WAIT.
1003
		if (la->rdomain != NULL &&
1004
		 */
1004
		    set_rdomain(listen_sock, la->rdomain) == -1) {
1005
		if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
1005
			close(listen_sock);
1006
		    &on, sizeof(on)) == -1)
1006
			continue;
1007
			error("setsockopt SO_REUSEADDR: %s", strerror(errno));
1007
		}
1008
1008
1009
		debug("Bind to port %s on %s.", strport, ntop);
1009
		debug("Bind to port %s on %s.", strport, ntop);
1010
1010
Lines 1022-1030 server_listen(void) Link Here
1022
		if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
1022
		if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
1023
			fatal("listen on [%s]:%s: %.100s",
1023
			fatal("listen on [%s]:%s: %.100s",
1024
			    ntop, strport, strerror(errno));
1024
			    ntop, strport, strerror(errno));
1025
		logit("Server listening on %s port %s.", ntop, strport);
1025
		logit("Server listening on %s port %s%s%s.",
1026
		    ntop, strport,
1027
		    la->rdomain == NULL ? "" : " rdomain ",
1028
		    la->rdomain == NULL ? "" : la->rdomain);
1026
	}
1029
	}
1027
	freeaddrinfo(options.listen_addrs);
1030
}
1031
1032
static void
1033
server_listen(void)
1034
{
1035
	u_int i;
1036
1037
	for (i = 0; i < options.num_listen_addrs; i++) {
1038
		listen_on_addrs(&options.listen_addrs[i]);
1039
		freeaddrinfo(options.listen_addrs[i].addrs);
1040
		free(options.listen_addrs[i].rdomain);
1041
		memset(&options.listen_addrs[i], 0,
1042
		    sizeof(options.listen_addrs[i]));
1043
	}
1044
	free(options.listen_addrs);
1045
	options.listen_addrs = NULL;
1046
	options.num_listen_addrs = 0;
1028
1047
1029
	if (!num_listen_socks)
1048
	if (!num_listen_socks)
1030
		fatal("Cannot bind any address.");
1049
		fatal("Cannot bind any address.");
1031
- 

Return to bug 2784