diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2019-01-06 18:41:11 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2019-01-06 18:41:11 +0100 |
commit | 5bfc4a32fdae8f43e97588d5575249f896a17376 (patch) | |
tree | 89ef109b8ffc0646301255a247d212f62bf148bf | |
parent | 1c952ba2060780fce830d427420b9d819f08880e (diff) | |
download | busybox-w32-5bfc4a32fdae8f43e97588d5575249f896a17376.tar.gz busybox-w32-5bfc4a32fdae8f43e97588d5575249f896a17376.tar.bz2 busybox-w32-5bfc4a32fdae8f43e97588d5575249f896a17376.zip |
telnet: speed up processing of network input
function old new delta
telnet_main 1482 1492 +10
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/telnet.c | 83 |
1 files changed, 43 insertions, 40 deletions
diff --git a/networking/telnet.c b/networking/telnet.c index 7f65ff3e6..0ee65c532 100644 --- a/networking/telnet.c +++ b/networking/telnet.c | |||
@@ -94,19 +94,19 @@ enum { | |||
94 | IACBUFSIZE = 128, | 94 | IACBUFSIZE = 128, |
95 | 95 | ||
96 | CHM_TRY = 0, | 96 | CHM_TRY = 0, |
97 | CHM_ON = 1, | 97 | CHM_ON = 1, |
98 | CHM_OFF = 2, | 98 | CHM_OFF = 2, |
99 | 99 | ||
100 | UF_ECHO = 0x01, | 100 | UF_ECHO = 0x01, |
101 | UF_SGA = 0x02, | 101 | UF_SGA = 0x02, |
102 | 102 | ||
103 | TS_NORMAL = 0, | 103 | TS_NORMAL = 0, |
104 | TS_COPY = 1, | 104 | TS_COPY = 1, |
105 | TS_IAC = 2, | 105 | TS_IAC = 2, |
106 | TS_OPT = 3, | 106 | TS_OPT = 3, |
107 | TS_SUB1 = 4, | 107 | TS_SUB1 = 4, |
108 | TS_SUB2 = 5, | 108 | TS_SUB2 = 5, |
109 | TS_CR = 6, | 109 | TS_CR = 6, |
110 | }; | 110 | }; |
111 | 111 | ||
112 | typedef unsigned char byte; | 112 | typedef unsigned char byte; |
@@ -244,25 +244,34 @@ static void handle_net_output(int len) | |||
244 | 244 | ||
245 | static void handle_net_input(int len) | 245 | static void handle_net_input(int len) |
246 | { | 246 | { |
247 | byte c; | ||
247 | int i; | 248 | int i; |
248 | int cstart = 0; | 249 | int cstart; |
249 | 250 | ||
250 | for (i = 0; i < len; i++) { | 251 | i = 0; |
251 | byte c = G.buf[i]; | 252 | //bb_error_msg("[%u,'%.*s']", G.telstate, len, G.buf); |
252 | 253 | if (G.telstate == TS_NORMAL) { /* most typical state */ | |
253 | if (G.telstate == TS_NORMAL) { /* most typical state */ | 254 | while (i < len) { |
254 | if (c == IAC) { | 255 | c = G.buf[i]; |
255 | cstart = i; | 256 | i++; |
256 | G.telstate = TS_IAC; | 257 | if (c == IAC) /* unlikely */ |
257 | } | 258 | goto got_IAC; |
258 | else if (c == '\r') { | 259 | if (c != '\r') /* likely */ |
259 | cstart = i + 1; | 260 | continue; |
260 | G.telstate = TS_CR; | 261 | G.telstate = TS_CR; |
261 | } | 262 | cstart = i; |
262 | /* No IACs were seen so far, no need to copy | 263 | goto got_special; |
263 | * bytes within G.buf: */ | ||
264 | continue; | ||
265 | } | 264 | } |
265 | full_write(STDOUT_FILENO, G.buf, len); | ||
266 | return; | ||
267 | got_IAC: | ||
268 | G.telstate = TS_IAC; | ||
269 | cstart = i - 1; | ||
270 | got_special: ; | ||
271 | } | ||
272 | |||
273 | for (; i < len; i++) { | ||
274 | c = G.buf[i]; | ||
266 | 275 | ||
267 | switch (G.telstate) { | 276 | switch (G.telstate) { |
268 | case TS_CR: | 277 | case TS_CR: |
@@ -278,20 +287,19 @@ static void handle_net_input(int len) | |||
278 | /* Similar to NORMAL, but in TS_COPY we need to copy bytes */ | 287 | /* Similar to NORMAL, but in TS_COPY we need to copy bytes */ |
279 | if (c == IAC) | 288 | if (c == IAC) |
280 | G.telstate = TS_IAC; | 289 | G.telstate = TS_IAC; |
281 | else | 290 | else { |
282 | G.buf[cstart++] = c; | 291 | G.buf[cstart++] = c; |
283 | if (c == '\r') | 292 | if (c == '\r') |
284 | G.telstate = TS_CR; | 293 | G.telstate = TS_CR; |
294 | } | ||
285 | break; | 295 | break; |
286 | 296 | ||
287 | case TS_IAC: /* Prev char was IAC */ | 297 | case TS_IAC: /* Prev char was IAC */ |
288 | if (c == IAC) { /* IAC IAC -> one IAC */ | 298 | switch (c) { |
299 | case IAC: /* IAC IAC -> one IAC */ | ||
289 | G.buf[cstart++] = c; | 300 | G.buf[cstart++] = c; |
290 | G.telstate = TS_COPY; | 301 | G.telstate = TS_COPY; |
291 | break; | 302 | break; |
292 | } | ||
293 | /* else */ | ||
294 | switch (c) { | ||
295 | case SB: | 303 | case SB: |
296 | G.telstate = TS_SUB1; | 304 | G.telstate = TS_SUB1; |
297 | break; | 305 | break; |
@@ -320,17 +328,12 @@ static void handle_net_input(int len) | |||
320 | } | 328 | } |
321 | } | 329 | } |
322 | 330 | ||
323 | if (G.telstate != TS_NORMAL) { | 331 | /* We had some IACs, or CR */ |
324 | /* We had some IACs, or CR */ | 332 | iac_flush(); |
325 | if (G.iaclen) | 333 | if (G.telstate == TS_COPY) /* we aren't in the middle of IAC */ |
326 | iac_flush(); | 334 | G.telstate = TS_NORMAL; |
327 | if (G.telstate == TS_COPY) /* we aren't in the middle of IAC */ | 335 | if (cstart != 0) |
328 | G.telstate = TS_NORMAL; | 336 | full_write(STDOUT_FILENO, G.buf, cstart); |
329 | len = cstart; | ||
330 | } | ||
331 | |||
332 | if (len) | ||
333 | full_write(STDOUT_FILENO, G.buf, len); | ||
334 | } | 337 | } |
335 | 338 | ||
336 | static void put_iac(int c) | 339 | static void put_iac(int c) |