[git commit] telnet: speed up processing of network input

Denys Vlasenko vda.linux at googlemail.com
Sun Jan 6 17:41:11 UTC 2019


commit: https://git.busybox.net/busybox/commit/?id=5bfc4a32fdae8f43e97588d5575249f896a17376
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
telnet_main                                         1482    1492     +10

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 networking/telnet.c | 83 +++++++++++++++++++++++++++--------------------------
 1 file 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 {
 	IACBUFSIZE  = 128,
 
 	CHM_TRY = 0,
-	CHM_ON = 1,
+	CHM_ON  = 1,
 	CHM_OFF = 2,
 
 	UF_ECHO = 0x01,
-	UF_SGA = 0x02,
+	UF_SGA  = 0x02,
 
 	TS_NORMAL = 0,
 	TS_COPY = 1,
-	TS_IAC = 2,
-	TS_OPT = 3,
+	TS_IAC  = 2,
+	TS_OPT  = 3,
 	TS_SUB1 = 4,
 	TS_SUB2 = 5,
-	TS_CR = 6,
+	TS_CR   = 6,
 };
 
 typedef unsigned char byte;
@@ -244,25 +244,34 @@ static void handle_net_output(int len)
 
 static void handle_net_input(int len)
 {
+	byte c;
 	int i;
-	int cstart = 0;
-
-	for (i = 0; i < len; i++) {
-		byte c = G.buf[i];
-
-		if (G.telstate == TS_NORMAL) { /* most typical state */
-			if (c == IAC) {
-				cstart = i;
-				G.telstate = TS_IAC;
-			}
-			else if (c == '\r') {
-				cstart = i + 1;
-				G.telstate = TS_CR;
-			}
-			/* No IACs were seen so far, no need to copy
-			 * bytes within G.buf: */
-			continue;
+	int cstart;
+
+	i = 0;
+	//bb_error_msg("[%u,'%.*s']", G.telstate, len, G.buf);
+	if (G.telstate == TS_NORMAL) { /* most typical state */
+		while (i < len) {
+			c = G.buf[i];
+			i++;
+			if (c == IAC) /* unlikely */
+				goto got_IAC;
+			if (c != '\r') /* likely */
+				continue;
+			G.telstate = TS_CR;
+			cstart = i;
+			goto got_special;
 		}
+		full_write(STDOUT_FILENO, G.buf, len);
+		return;
+ got_IAC:
+		G.telstate = TS_IAC;
+		cstart = i - 1;
+ got_special: ;
+	}
+
+	for (; i < len; i++) {
+		c = G.buf[i];
 
 		switch (G.telstate) {
 		case TS_CR:
@@ -278,20 +287,19 @@ static void handle_net_input(int len)
 			/* Similar to NORMAL, but in TS_COPY we need to copy bytes */
 			if (c == IAC)
 				G.telstate = TS_IAC;
-			else
+			else {
 				G.buf[cstart++] = c;
-			if (c == '\r')
-				G.telstate = TS_CR;
+				if (c == '\r')
+					G.telstate = TS_CR;
+			}
 			break;
 
 		case TS_IAC: /* Prev char was IAC */
-			if (c == IAC) { /* IAC IAC -> one IAC */
+			switch (c) {
+			case IAC: /* IAC IAC -> one IAC */
 				G.buf[cstart++] = c;
 				G.telstate = TS_COPY;
 				break;
-			}
-			/* else */
-			switch (c) {
 			case SB:
 				G.telstate = TS_SUB1;
 				break;
@@ -320,17 +328,12 @@ static void handle_net_input(int len)
 		}
 	}
 
-	if (G.telstate != TS_NORMAL) {
-		/* We had some IACs, or CR */
-		if (G.iaclen)
-			iac_flush();
-		if (G.telstate == TS_COPY) /* we aren't in the middle of IAC */
-			G.telstate = TS_NORMAL;
-		len = cstart;
-	}
-
-	if (len)
-		full_write(STDOUT_FILENO, G.buf, len);
+	/* We had some IACs, or CR */
+	iac_flush();
+	if (G.telstate == TS_COPY) /* we aren't in the middle of IAC */
+		G.telstate = TS_NORMAL;
+	if (cstart != 0)
+		full_write(STDOUT_FILENO, G.buf, cstart);
 }
 
 static void put_iac(int c)


More information about the busybox-cvs mailing list