Mercurial > dropbear
comparison common-session.c @ 435:337c45621e81
merge of 'a9b0496634cdd25647b65e585cc3240f3fa699ee'
and 'c22be8b8f570b48e9662dac32c7b3e7148a42206'
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 22 Feb 2007 14:53:49 +0000 |
parents | a01c0c8e543a |
children | 9c61e7af0156 |
comparison
equal
deleted
inserted
replaced
434:0aaaf68e97dc | 435:337c45621e81 |
---|---|
59 ses.sock = sock; | 59 ses.sock = sock; |
60 ses.maxfd = sock; | 60 ses.maxfd = sock; |
61 | 61 |
62 ses.connecttimeout = 0; | 62 ses.connecttimeout = 0; |
63 | 63 |
64 if (pipe(ses.signal_pipe) < 0) { | |
65 dropbear_exit("signal pipe failed"); | |
66 } | |
67 setnonblocking(ses.signal_pipe[0]); | |
68 setnonblocking(ses.signal_pipe[1]); | |
69 | |
64 kexfirstinitialise(); /* initialise the kex state */ | 70 kexfirstinitialise(); /* initialise the kex state */ |
65 | 71 |
66 ses.writepayload = buf_new(MAX_TRANS_PAYLOAD_LEN); | 72 ses.writepayload = buf_new(MAX_TRANS_PAYLOAD_LEN); |
67 ses.transseq = 0; | 73 ses.transseq = 0; |
68 | 74 |
105 ses.remoteident = NULL; | 111 ses.remoteident = NULL; |
106 | 112 |
107 ses.chantypes = NULL; | 113 ses.chantypes = NULL; |
108 | 114 |
109 ses.allowprivport = 0; | 115 ses.allowprivport = 0; |
110 | |
111 | 116 |
112 TRACE(("leave session_init")) | 117 TRACE(("leave session_init")) |
113 } | 118 } |
114 | 119 |
115 void session_loop(void(*loophandler)()) { | 120 void session_loop(void(*loophandler)()) { |
130 FD_SET(ses.sock, &readfd); | 135 FD_SET(ses.sock, &readfd); |
131 if (!isempty(&ses.writequeue)) { | 136 if (!isempty(&ses.writequeue)) { |
132 FD_SET(ses.sock, &writefd); | 137 FD_SET(ses.sock, &writefd); |
133 } | 138 } |
134 } | 139 } |
140 | |
141 /* We get woken up when signal handlers write to this pipe. | |
142 SIGCHLD in svr-chansession is the only one currently. */ | |
143 FD_SET(ses.signal_pipe[0], &readfd); | |
135 | 144 |
136 /* set up for channels which require reading/writing */ | 145 /* set up for channels which require reading/writing */ |
137 if (ses.dataallowed) { | 146 if (ses.dataallowed) { |
138 setchannelfds(&readfd, &writefd); | 147 setchannelfds(&readfd, &writefd); |
139 } | 148 } |
141 | 150 |
142 if (exitflag) { | 151 if (exitflag) { |
143 dropbear_exit("Terminated by signal"); | 152 dropbear_exit("Terminated by signal"); |
144 } | 153 } |
145 | 154 |
146 if (val < 0) { | 155 if (val < 0 && errno != EINTR) { |
147 if (errno == EINTR) { | 156 dropbear_exit("Error in select"); |
148 /* This must happen even if we've been interrupted, so that | 157 } |
149 * changed signal-handler vars can take effect etc */ | 158 |
150 if (loophandler) { | 159 if (val <= 0) { |
151 loophandler(); | 160 /* If we were interrupted or the select timed out, we still |
152 } | 161 * want to iterate over channels etc for reading, to handle |
153 continue; | 162 * server processes exiting etc. |
154 } else { | 163 * We don't want to read/write FDs. */ |
155 dropbear_exit("Error in select"); | 164 FD_ZERO(&writefd); |
156 } | 165 FD_ZERO(&readfd); |
166 } | |
167 | |
168 /* We'll just empty out the pipe if required. We don't do | |
169 any thing with the data, since the pipe's purpose is purely to | |
170 wake up the select() above. */ | |
171 if (FD_ISSET(ses.signal_pipe[0], &readfd)) { | |
172 char x; | |
173 while (read(ses.signal_pipe[0], &x, 1) > 0) {} | |
157 } | 174 } |
158 | 175 |
159 /* check for auth timeout, rekeying required etc */ | 176 /* check for auth timeout, rekeying required etc */ |
160 checktimeouts(); | 177 checktimeouts(); |
161 | |
162 if (val == 0) { | |
163 /* timeout */ | |
164 TRACE(("select timeout")) | |
165 continue; | |
166 } | |
167 | 178 |
168 /* process session socket's incoming/outgoing data */ | 179 /* process session socket's incoming/outgoing data */ |
169 if (ses.sock != -1) { | 180 if (ses.sock != -1) { |
170 if (FD_ISSET(ses.sock, &writefd) && !isempty(&ses.writequeue)) { | 181 if (FD_ISSET(ses.sock, &writefd) && !isempty(&ses.writequeue)) { |
171 write_packet(); | 182 write_packet(); |
227 int i; | 238 int i; |
228 | 239 |
229 /* write our version string, this blocks */ | 240 /* write our version string, this blocks */ |
230 if (atomicio(write, ses.sock, LOCAL_IDENT "\r\n", | 241 if (atomicio(write, ses.sock, LOCAL_IDENT "\r\n", |
231 strlen(LOCAL_IDENT "\r\n")) == DROPBEAR_FAILURE) { | 242 strlen(LOCAL_IDENT "\r\n")) == DROPBEAR_FAILURE) { |
232 dropbear_exit("Error writing ident string"); | 243 ses.remoteclosed(); |
233 } | 244 } |
234 | 245 |
235 /* If they send more than 50 lines, something is wrong */ | 246 /* If they send more than 50 lines, something is wrong */ |
236 for (i = 0; i < 50; i++) { | 247 for (i = 0; i < 50; i++) { |
237 len = ident_readln(ses.sock, linebuf, sizeof(linebuf)); | 248 len = ident_readln(ses.sock, linebuf, sizeof(linebuf)); |
248 } | 259 } |
249 } | 260 } |
250 | 261 |
251 if (!done) { | 262 if (!done) { |
252 TRACE(("err: %s for '%s'\n", strerror(errno), linebuf)) | 263 TRACE(("err: %s for '%s'\n", strerror(errno), linebuf)) |
253 dropbear_exit("Failed to get remote version"); | 264 ses.remoteclosed(); |
254 } else { | 265 } else { |
255 /* linebuf is already null terminated */ | 266 /* linebuf is already null terminated */ |
256 ses.remoteident = m_malloc(len); | 267 ses.remoteident = m_malloc(len); |
257 memcpy(ses.remoteident, linebuf, len); | 268 memcpy(ses.remoteident, linebuf, len); |
258 } | 269 } |