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

Collapse All | Expand All

(-)a/sshd.c (-7 / +61 lines)
Lines 217-222 u_int utmp_len = HOST_NAME_MAX+1; Link Here
217
int *startup_pipes = NULL;
217
int *startup_pipes = NULL;
218
int startup_pipe;		/* in child */
218
int startup_pipe;		/* in child */
219
219
220
/* options.max_startup sized array of fd ints */
221
int *listener_pipes = NULL;
222
220
/* variables used for privilege separation */
223
/* variables used for privilege separation */
221
int use_privsep = -1;
224
int use_privsep = -1;
222
struct monitor *pmonitor = NULL;
225
struct monitor *pmonitor = NULL;
Lines 257-263 close_listen_socks(void) Link Here
257
}
260
}
258
261
259
static void
262
static void
260
close_startup_pipes(void)
263
close_notification_pipes(void)
261
{
264
{
262
	int i;
265
	int i;
263
266
Lines 265-270 close_startup_pipes(void) Link Here
265
		for (i = 0; i < options.max_startups; i++)
268
		for (i = 0; i < options.max_startups; i++)
266
			if (startup_pipes[i] != -1)
269
			if (startup_pipes[i] != -1)
267
				close(startup_pipes[i]);
270
				close(startup_pipes[i]);
271
272
	if (listener_pipes)
273
		for (i = 0; i < options.max_startups; i++)
274
			if (listener_pipes[i] != -1)
275
				close(listener_pipes[i]);
268
}
276
}
269
277
270
/*
278
/*
Lines 295-301 sighup_restart(void) Link Here
295
		unlink(options.pid_file);
303
		unlink(options.pid_file);
296
	platform_pre_restart();
304
	platform_pre_restart();
297
	close_listen_socks();
305
	close_listen_socks();
298
	close_startup_pipes();
306
	close_notification_pipes();
299
	alarm(0);  /* alarm timer persists across exec */
307
	alarm(0);  /* alarm timer persists across exec */
300
	signal(SIGHUP, SIG_IGN); /* will be restored after exec */
308
	signal(SIGHUP, SIG_IGN); /* will be restored after exec */
301
	execv(saved_argv[0], saved_argv);
309
	execv(saved_argv[0], saved_argv);
Lines 1022-1029 server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) Link Here
1022
{
1030
{
1023
	fd_set *fdset;
1031
	fd_set *fdset;
1024
	int i, j, ret, maxfd;
1032
	int i, j, ret, maxfd;
1025
	int startups = 0;
1033
	int startups = 0, listening_children = 0;
1026
	int startup_p[2] = { -1 , -1 };
1034
	int startup_p[2] = { -1 , -1 };
1035
	int listener_p[2] = { -1 , -1 };
1027
	struct sockaddr_storage from;
1036
	struct sockaddr_storage from;
1028
	socklen_t fromlen;
1037
	socklen_t fromlen;
1029
	pid_t pid;
1038
	pid_t pid;
Lines 1040-1051 server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) Link Here
1040
	for (i = 0; i < options.max_startups; i++)
1049
	for (i = 0; i < options.max_startups; i++)
1041
		startup_pipes[i] = -1;
1050
		startup_pipes[i] = -1;
1042
1051
1052
	/* pipes connected to listening childs */
1053
	listener_pipes = xcalloc(options.max_startups, sizeof(int));
1054
	for (i = 0; i < options.max_startups; i++)
1055
		listener_pipes[i] = -1;
1056
1043
	/*
1057
	/*
1044
	 * Stay listening for connections until the system crashes or
1058
	 * Stay listening for connections until the system crashes or
1045
	 * the daemon is killed with a signal.
1059
	 * the daemon is killed with a signal.
1046
	 */
1060
	 */
1047
	for (;;) {
1061
	for (;;) {
1048
		if (received_sighup)
1062
		if (received_sighup &&
1063
		    listening_children == 0) // TODO too heavy traffic may prevent us restarting forever
1049
			sighup_restart();
1064
			sighup_restart();
1050
		free(fdset);
1065
		free(fdset);
1051
		fdset = xcalloc(howmany(maxfd + 1, NFDBITS),
1066
		fdset = xcalloc(howmany(maxfd + 1, NFDBITS),
Lines 1054-1061 server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) Link Here
1054
		for (i = 0; i < num_listen_socks; i++)
1069
		for (i = 0; i < num_listen_socks; i++)
1055
			FD_SET(listen_socks[i], fdset);
1070
			FD_SET(listen_socks[i], fdset);
1056
		for (i = 0; i < options.max_startups; i++)
1071
		for (i = 0; i < options.max_startups; i++)
1057
			if (startup_pipes[i] != -1)
1072
			if (startup_pipes[i] != -1) {
1058
				FD_SET(startup_pipes[i], fdset);
1073
				FD_SET(startup_pipes[i], fdset);
1074
				// assert(listener_pipes[i] != -1)
1075
				FD_SET(listener_pipes[i], fdset);
1076
			}
1059
1077
1060
		/* Wait in select until there is a connection. */
1078
		/* Wait in select until there is a connection. */
1061
		ret = select(maxfd+1, fdset, NULL, NULL, NULL);
1079
		ret = select(maxfd+1, fdset, NULL, NULL, NULL);
Lines 1072-1077 server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) Link Here
1072
		if (ret < 0)
1090
		if (ret < 0)
1073
			continue;
1091
			continue;
1074
1092
1093
		for (i = 0; i < options.max_startups; i++)
1094
			if (listener_pipes[i] != -1 &&
1095
			    FD_ISSET(listener_pipes[i], fdset)) {
1096
				/*
1097
				 * the read end of the pipe is ready
1098
				 * if the child has closed the pipe
1099
				 * after closing listen socket
1100
				 * or if the child has died (that is handled
1101
				 * via startup_pipes)
1102
				 */
1103
				close(listener_pipes[i]);
1104
				listener_pipes[i] = -1;
1105
				listening_children--;
1106
			}
1107
1075
		for (i = 0; i < options.max_startups; i++)
1108
		for (i = 0; i < options.max_startups; i++)
1076
			if (startup_pipes[i] != -1 &&
1109
			if (startup_pipes[i] != -1 &&
1077
			    FD_ISSET(startup_pipes[i], fdset)) {
1110
			    FD_ISSET(startup_pipes[i], fdset)) {
Lines 1085-1090 server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) Link Here
1085
				startup_pipes[i] = -1;
1118
				startup_pipes[i] = -1;
1086
				startups--;
1119
				startups--;
1087
			}
1120
			}
1121
1122
		/* Delay accepting new clients after we restart */
1123
		if (received_sighup)
1124
			continue;
1088
		for (i = 0; i < num_listen_socks; i++) {
1125
		for (i = 0; i < num_listen_socks; i++) {
1089
			if (!FD_ISSET(listen_socks[i], fdset))
1126
			if (!FD_ISSET(listen_socks[i], fdset))
1090
				continue;
1127
				continue;
Lines 1121-1126 server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) Link Here
1121
				close(*newsock);
1158
				close(*newsock);
1122
				continue;
1159
				continue;
1123
			}
1160
			}
1161
			if (pipe(listener_p) == -1) {
1162
				close(startup_p[0]);
1163
				close(startup_p[1]);
1164
				close(*newsock);
1165
				continue;
1166
			}
1124
1167
1125
			if (rexec_flag && socketpair(AF_UNIX,
1168
			if (rexec_flag && socketpair(AF_UNIX,
1126
			    SOCK_STREAM, 0, config_s) == -1) {
1169
			    SOCK_STREAM, 0, config_s) == -1) {
Lines 1129-1134 server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) Link Here
1129
				close(*newsock);
1172
				close(*newsock);
1130
				close(startup_p[0]);
1173
				close(startup_p[0]);
1131
				close(startup_p[1]);
1174
				close(startup_p[1]);
1175
				close(listener_p[0]);
1176
				close(listener_p[1]);
1132
				continue;
1177
				continue;
1133
			}
1178
			}
1134
1179
Lines 1138-1143 server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) Link Here
1138
					if (maxfd < startup_p[0])
1183
					if (maxfd < startup_p[0])
1139
						maxfd = startup_p[0];
1184
						maxfd = startup_p[0];
1140
					startups++;
1185
					startups++;
1186
1187
					listener_pipes[j] = listener_p[0];
1188
					if (maxfd < listener_p[0])
1189
						maxfd = listener_p[0];
1190
					listening_children++;
1141
					break;
1191
					break;
1142
				}
1192
				}
1143
1193
Lines 1157-1162 server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) Link Here
1157
				*sock_out = *newsock;
1207
				*sock_out = *newsock;
1158
				close(startup_p[0]);
1208
				close(startup_p[0]);
1159
				close(startup_p[1]);
1209
				close(startup_p[1]);
1210
				close(listener_p[0]);
1211
				close(listener_p[1]);
1160
				startup_pipe = -1;
1212
				startup_pipe = -1;
1161
				pid = getpid();
1213
				pid = getpid();
1162
				if (rexec_flag) {
1214
				if (rexec_flag) {
Lines 1183-1190 server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) Link Here
1183
				 */
1235
				 */
1184
				platform_post_fork_child();
1236
				platform_post_fork_child();
1185
				startup_pipe = startup_p[1];
1237
				startup_pipe = startup_p[1];
1186
				close_startup_pipes();
1238
				close_notification_pipes();
1187
				close_listen_socks();
1239
				close_listen_socks();
1240
				/* Notify parent about free'd listen sock */
1241
				close(listener_p[1]);
1188
				*sock_in = *newsock;
1242
				*sock_in = *newsock;
1189
				*sock_out = *newsock;
1243
				*sock_out = *newsock;
1190
				log_init(__progname,
1244
				log_init(__progname,
Lines 1204-1209 server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) Link Here
1204
				debug("Forked child %ld.", (long)pid);
1258
				debug("Forked child %ld.", (long)pid);
1205
1259
1206
			close(startup_p[1]);
1260
			close(startup_p[1]);
1261
			close(listener_p[1]);
1207
1262
1208
			if (rexec_flag) {
1263
			if (rexec_flag) {
1209
				send_rexec_state(config_s[0], cfg);
1264
				send_rexec_state(config_s[0], cfg);
1210
- 

Return to bug 2953