diff options
| author | beck <> | 2019-11-13 04:10:38 +0000 |
|---|---|---|
| committer | beck <> | 2019-11-13 04:10:38 +0000 |
| commit | fadef512b562edf09855c18f7b45dccef082b168 (patch) | |
| tree | b9dc89ebc1f5efebbaf280c80b0cc30be3db858a /src | |
| parent | ded8273c2e30995cb226491bc62d5375ad3763cc (diff) | |
| download | openbsd-fadef512b562edf09855c18f7b45dccef082b168.tar.gz openbsd-fadef512b562edf09855c18f7b45dccef082b168.tar.bz2 openbsd-fadef512b562edf09855c18f7b45dccef082b168.zip | |
refactor the nc pool loop to not shut down the socket early, and
to handle tls_shutdown correctly if using TLS, doing tls_shutdown
correctly if we are using the -N flag
ok sthen@
Diffstat (limited to 'src')
| -rw-r--r-- | src/usr.bin/nc/netcat.c | 100 |
1 files changed, 64 insertions, 36 deletions
diff --git a/src/usr.bin/nc/netcat.c b/src/usr.bin/nc/netcat.c index a53fe1c4cd..1dc95e9f36 100644 --- a/src/usr.bin/nc/netcat.c +++ b/src/usr.bin/nc/netcat.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: netcat.c,v 1.210 2019/11/04 17:33:28 millert Exp $ */ | 1 | /* $OpenBSD: netcat.c,v 1.211 2019/11/13 04:10:38 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> | 3 | * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> |
| 4 | * Copyright (c) 2015 Bob Beck. All rights reserved. | 4 | * Copyright (c) 2015 Bob Beck. All rights reserved. |
| @@ -1103,13 +1103,14 @@ void | |||
| 1103 | readwrite(int net_fd, struct tls *tls_ctx) | 1103 | readwrite(int net_fd, struct tls *tls_ctx) |
| 1104 | { | 1104 | { |
| 1105 | struct pollfd pfd[4]; | 1105 | struct pollfd pfd[4]; |
| 1106 | int gone[4] = { 0 }; | ||
| 1106 | int stdin_fd = STDIN_FILENO; | 1107 | int stdin_fd = STDIN_FILENO; |
| 1107 | int stdout_fd = STDOUT_FILENO; | 1108 | int stdout_fd = STDOUT_FILENO; |
| 1108 | unsigned char netinbuf[BUFSIZE]; | 1109 | unsigned char netinbuf[BUFSIZE]; |
| 1109 | size_t netinbufpos = 0; | 1110 | size_t netinbufpos = 0; |
| 1110 | unsigned char stdinbuf[BUFSIZE]; | 1111 | unsigned char stdinbuf[BUFSIZE]; |
| 1111 | size_t stdinbufpos = 0; | 1112 | size_t stdinbufpos = 0; |
| 1112 | int n, num_fds; | 1113 | int n, num_fds, shutdown_netin, shutdown_netout; |
| 1113 | ssize_t ret; | 1114 | ssize_t ret; |
| 1114 | 1115 | ||
| 1115 | /* don't read from stdin if requested */ | 1116 | /* don't read from stdin if requested */ |
| @@ -1132,17 +1133,20 @@ readwrite(int net_fd, struct tls *tls_ctx) | |||
| 1132 | pfd[POLL_STDOUT].fd = stdout_fd; | 1133 | pfd[POLL_STDOUT].fd = stdout_fd; |
| 1133 | pfd[POLL_STDOUT].events = 0; | 1134 | pfd[POLL_STDOUT].events = 0; |
| 1134 | 1135 | ||
| 1136 | /* used to indicate we wish to shut down the network socket */ | ||
| 1137 | shutdown_netin = shutdown_netout = 0; | ||
| 1138 | |||
| 1135 | while (1) { | 1139 | while (1) { |
| 1136 | /* both inputs are gone, buffers are empty, we are done */ | 1140 | /* both inputs are gone, buffers are empty, we are done */ |
| 1137 | if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1 && | 1141 | if (gone[POLL_STDIN] && gone[POLL_NETIN] && |
| 1138 | stdinbufpos == 0 && netinbufpos == 0) | 1142 | stdinbufpos == 0 && netinbufpos == 0) |
| 1139 | return; | 1143 | return; |
| 1140 | /* both outputs are gone, we can't continue */ | 1144 | /* both outputs are gone, we can't continue */ |
| 1141 | if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1) | 1145 | if (gone[POLL_NETOUT] && gone[POLL_STDOUT]) |
| 1142 | return; | 1146 | return; |
| 1143 | /* listen and net in gone, queues empty, done */ | 1147 | /* listen and net in gone, queues empty, done */ |
| 1144 | if (lflag && pfd[POLL_NETIN].fd == -1 && | 1148 | if (lflag && gone[POLL_NETIN] && stdinbufpos == 0 |
| 1145 | stdinbufpos == 0 && netinbufpos == 0) | 1149 | && netinbufpos == 0) |
| 1146 | return; | 1150 | return; |
| 1147 | 1151 | ||
| 1148 | /* help says -i is for "wait between lines sent". We read and | 1152 | /* help says -i is for "wait between lines sent". We read and |
| @@ -1151,6 +1155,12 @@ readwrite(int net_fd, struct tls *tls_ctx) | |||
| 1151 | if (iflag) | 1155 | if (iflag) |
| 1152 | sleep(iflag); | 1156 | sleep(iflag); |
| 1153 | 1157 | ||
| 1158 | /* If it's gone, take it away from poll */ | ||
| 1159 | for (n = 0; n < 4; n++) { | ||
| 1160 | if (gone[n]) | ||
| 1161 | pfd[n].events = pfd[n].revents = 0; | ||
| 1162 | } | ||
| 1163 | |||
| 1154 | /* poll */ | 1164 | /* poll */ |
| 1155 | num_fds = poll(pfd, 4, timeout); | 1165 | num_fds = poll(pfd, 4, timeout); |
| 1156 | 1166 | ||
| @@ -1165,36 +1175,36 @@ readwrite(int net_fd, struct tls *tls_ctx) | |||
| 1165 | /* treat socket error conditions */ | 1175 | /* treat socket error conditions */ |
| 1166 | for (n = 0; n < 4; n++) { | 1176 | for (n = 0; n < 4; n++) { |
| 1167 | if (pfd[n].revents & (POLLERR|POLLNVAL)) { | 1177 | if (pfd[n].revents & (POLLERR|POLLNVAL)) { |
| 1168 | pfd[n].fd = -1; | 1178 | gone[n] = 1; |
| 1169 | } | 1179 | } |
| 1170 | } | 1180 | } |
| 1171 | /* reading is possible after HUP */ | 1181 | /* reading is possible after HUP */ |
| 1172 | if (pfd[POLL_STDIN].events & POLLIN && | 1182 | if (pfd[POLL_STDIN].events & POLLIN && |
| 1173 | pfd[POLL_STDIN].revents & POLLHUP && | 1183 | pfd[POLL_STDIN].revents & POLLHUP && |
| 1174 | !(pfd[POLL_STDIN].revents & POLLIN)) | 1184 | !(pfd[POLL_STDIN].revents & POLLIN)) |
| 1175 | pfd[POLL_STDIN].fd = -1; | 1185 | gone[POLL_STDIN] = 1; |
| 1176 | 1186 | ||
| 1177 | if (pfd[POLL_NETIN].events & POLLIN && | 1187 | if (pfd[POLL_NETIN].events & POLLIN && |
| 1178 | pfd[POLL_NETIN].revents & POLLHUP && | 1188 | pfd[POLL_NETIN].revents & POLLHUP && |
| 1179 | !(pfd[POLL_NETIN].revents & POLLIN)) | 1189 | !(pfd[POLL_NETIN].revents & POLLIN)) |
| 1180 | pfd[POLL_NETIN].fd = -1; | 1190 | gone[POLL_NETIN] = 1; |
| 1181 | 1191 | ||
| 1182 | if (pfd[POLL_NETOUT].revents & POLLHUP) { | 1192 | if (pfd[POLL_NETOUT].revents & POLLHUP) { |
| 1183 | if (Nflag) | 1193 | if (Nflag) |
| 1184 | shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); | 1194 | shutdown_netout = 1; |
| 1185 | pfd[POLL_NETOUT].fd = -1; | 1195 | gone[POLL_NETOUT] = 1; |
| 1186 | } | 1196 | } |
| 1187 | /* if HUP, stop watching stdout */ | ||
| 1188 | if (pfd[POLL_STDOUT].revents & POLLHUP) | ||
| 1189 | pfd[POLL_STDOUT].fd = -1; | ||
| 1190 | /* if no net out, stop watching stdin */ | 1197 | /* if no net out, stop watching stdin */ |
| 1191 | if (pfd[POLL_NETOUT].fd == -1) | 1198 | if (gone[POLL_NETOUT]) |
| 1192 | pfd[POLL_STDIN].fd = -1; | 1199 | gone[POLL_STDIN] = 1; |
| 1200 | |||
| 1201 | /* if stdout HUP's, stop watching stdout */ | ||
| 1202 | if (pfd[POLL_STDOUT].revents & POLLHUP) | ||
| 1203 | gone[POLL_STDOUT] = 1; | ||
| 1193 | /* if no stdout, stop watching net in */ | 1204 | /* if no stdout, stop watching net in */ |
| 1194 | if (pfd[POLL_STDOUT].fd == -1) { | 1205 | if (gone[POLL_STDOUT]) { |
| 1195 | if (pfd[POLL_NETIN].fd != -1) | 1206 | shutdown_netin = 1; |
| 1196 | shutdown(pfd[POLL_NETIN].fd, SHUT_RD); | 1207 | gone[POLL_NETIN] = 1; |
| 1197 | pfd[POLL_NETIN].fd = -1; | ||
| 1198 | } | 1208 | } |
| 1199 | 1209 | ||
| 1200 | /* try to read from stdin */ | 1210 | /* try to read from stdin */ |
| @@ -1206,7 +1216,7 @@ readwrite(int net_fd, struct tls *tls_ctx) | |||
| 1206 | else if (ret == TLS_WANT_POLLOUT) | 1216 | else if (ret == TLS_WANT_POLLOUT) |
| 1207 | pfd[POLL_STDIN].events = POLLOUT; | 1217 | pfd[POLL_STDIN].events = POLLOUT; |
| 1208 | else if (ret == 0 || ret == -1) | 1218 | else if (ret == 0 || ret == -1) |
| 1209 | pfd[POLL_STDIN].fd = -1; | 1219 | gone[POLL_STDIN] = 1; |
| 1210 | /* read something - poll net out */ | 1220 | /* read something - poll net out */ |
| 1211 | if (stdinbufpos > 0) | 1221 | if (stdinbufpos > 0) |
| 1212 | pfd[POLL_NETOUT].events = POLLOUT; | 1222 | pfd[POLL_NETOUT].events = POLLOUT; |
| @@ -1223,7 +1233,7 @@ readwrite(int net_fd, struct tls *tls_ctx) | |||
| 1223 | else if (ret == TLS_WANT_POLLOUT) | 1233 | else if (ret == TLS_WANT_POLLOUT) |
| 1224 | pfd[POLL_NETOUT].events = POLLOUT; | 1234 | pfd[POLL_NETOUT].events = POLLOUT; |
| 1225 | else if (ret == -1) | 1235 | else if (ret == -1) |
| 1226 | pfd[POLL_NETOUT].fd = -1; | 1236 | gone[POLL_NETOUT] = 1; |
| 1227 | /* buffer empty - remove self from polling */ | 1237 | /* buffer empty - remove self from polling */ |
| 1228 | if (stdinbufpos == 0) | 1238 | if (stdinbufpos == 0) |
| 1229 | pfd[POLL_NETOUT].events = 0; | 1239 | pfd[POLL_NETOUT].events = 0; |
| @@ -1240,17 +1250,15 @@ readwrite(int net_fd, struct tls *tls_ctx) | |||
| 1240 | else if (ret == TLS_WANT_POLLOUT) | 1250 | else if (ret == TLS_WANT_POLLOUT) |
| 1241 | pfd[POLL_NETIN].events = POLLOUT; | 1251 | pfd[POLL_NETIN].events = POLLOUT; |
| 1242 | else if (ret == -1) | 1252 | else if (ret == -1) |
| 1243 | pfd[POLL_NETIN].fd = -1; | 1253 | gone[POLL_NETIN] = 1; |
| 1244 | /* eof on net in - remove from pfd */ | 1254 | /* eof on net in - remove from pfd */ |
| 1245 | if (ret == 0) { | 1255 | if (ret == 0) { |
| 1246 | shutdown(pfd[POLL_NETIN].fd, SHUT_RD); | 1256 | gone[POLL_NETIN] = 1; |
| 1247 | pfd[POLL_NETIN].fd = -1; | ||
| 1248 | } | 1257 | } |
| 1249 | if (recvlimit > 0 && ++recvcount >= recvlimit) { | 1258 | if (recvlimit > 0 && ++recvcount >= recvlimit) { |
| 1250 | if (pfd[POLL_NETIN].fd != -1) | 1259 | shutdown_netin = 1; |
| 1251 | shutdown(pfd[POLL_NETIN].fd, SHUT_RD); | 1260 | gone[POLL_NETIN] = 1; |
| 1252 | pfd[POLL_NETIN].fd = -1; | 1261 | gone[POLL_STDIN] = 1; |
| 1253 | pfd[POLL_STDIN].fd = -1; | ||
| 1254 | } | 1262 | } |
| 1255 | /* read something - poll stdout */ | 1263 | /* read something - poll stdout */ |
| 1256 | if (netinbufpos > 0) | 1264 | if (netinbufpos > 0) |
| @@ -1272,7 +1280,7 @@ readwrite(int net_fd, struct tls *tls_ctx) | |||
| 1272 | else if (ret == TLS_WANT_POLLOUT) | 1280 | else if (ret == TLS_WANT_POLLOUT) |
| 1273 | pfd[POLL_STDOUT].events = POLLOUT; | 1281 | pfd[POLL_STDOUT].events = POLLOUT; |
| 1274 | else if (ret == -1) | 1282 | else if (ret == -1) |
| 1275 | pfd[POLL_STDOUT].fd = -1; | 1283 | gone[POLL_STDOUT] = 1; |
| 1276 | /* buffer empty - remove self from polling */ | 1284 | /* buffer empty - remove self from polling */ |
| 1277 | if (netinbufpos == 0) | 1285 | if (netinbufpos == 0) |
| 1278 | pfd[POLL_STDOUT].events = 0; | 1286 | pfd[POLL_STDOUT].events = 0; |
| @@ -1282,14 +1290,34 @@ readwrite(int net_fd, struct tls *tls_ctx) | |||
| 1282 | } | 1290 | } |
| 1283 | 1291 | ||
| 1284 | /* stdin gone and queue empty? */ | 1292 | /* stdin gone and queue empty? */ |
| 1285 | if (pfd[POLL_STDIN].fd == -1 && stdinbufpos == 0) { | 1293 | if (gone[POLL_STDIN] && stdinbufpos == 0) { |
| 1286 | if (pfd[POLL_NETOUT].fd != -1 && Nflag) | 1294 | if (Nflag) { |
| 1287 | shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); | 1295 | shutdown_netin = 1; |
| 1288 | pfd[POLL_NETOUT].fd = -1; | 1296 | shutdown_netout = 1; |
| 1297 | } | ||
| 1298 | gone[POLL_NETOUT] = 1; | ||
| 1289 | } | 1299 | } |
| 1290 | /* net in gone and queue empty? */ | 1300 | /* net in gone and queue empty? */ |
| 1291 | if (pfd[POLL_NETIN].fd == -1 && netinbufpos == 0) { | 1301 | if (gone[POLL_NETIN] && netinbufpos == 0) { |
| 1292 | pfd[POLL_STDOUT].fd = -1; | 1302 | if (Nflag) { |
| 1303 | shutdown_netin = 1; | ||
| 1304 | shutdown_netout = 1; | ||
| 1305 | } | ||
| 1306 | gone[POLL_STDOUT] = 1; | ||
| 1307 | } | ||
| 1308 | |||
| 1309 | /* call tls_close if any part of the network socket is closing */ | ||
| 1310 | if ((shutdown_netin || shutdown_netout) && usetls) { | ||
| 1311 | timeout_tls(pfd[POLL_NETIN].fd, tls_ctx, tls_close); | ||
| 1312 | shutdown_netout = shutdown_netin = 1; | ||
| 1313 | } | ||
| 1314 | if (shutdown_netin) { | ||
| 1315 | shutdown(pfd[POLL_NETIN].fd, SHUT_RD); | ||
| 1316 | gone[POLL_NETIN] = 1; | ||
| 1317 | } | ||
| 1318 | if (shutdown_netout) { | ||
| 1319 | shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); | ||
| 1320 | gone[POLL_NETOUT] = 1; | ||
| 1293 | } | 1321 | } |
| 1294 | } | 1322 | } |
| 1295 | } | 1323 | } |
