Ver código fonte

telnet: handle "quit" command properly

Sergey Alirzaev 5 anos atrás
pai
commit
6402e09567
2 arquivos alterados com 35 adições e 35 exclusões
  1. 35 30
      modules/Telnet_Server/telnet_server.c
  2. 0 5
      modules/cli/cli.h

+ 35 - 30
modules/Telnet_Server/telnet_server.c

@@ -38,13 +38,15 @@
 // States
 //
 
-#define STATE_NORMAL 0
-#define STATE_IAC    1
-#define STATE_OPT    2
-#define STATE_SB     3
-#define STATE_OPTDAT 4
-#define STATE_SE     5
-#define STATE_CLOSE	 6
+typedef enum {
+	TELNET_STATE_NORMAL = 0,
+	TELNET_STATE_IAC,
+	TELNET_STATE_OPT,
+	TELNET_STATE_SB,
+	TELNET_STATE_OPTDAT,
+	//TELNET_STATE_SE,
+	TELNET_STATE_CLOSE,
+} telnet_state_t;
 
 //
 // Special telnet characters
@@ -156,7 +158,7 @@
  * A telnet connection structure.
  */
 typedef struct{
-	uint8_t state;
+	telnet_state_t state;
 	uint8_t code;
 	char buf[cmdMAX_INPUT_SIZE];
 	uint_fast8_t bufptr;
@@ -207,7 +209,7 @@ extern SETTINGS_t sSettings;
 void
 telnetd_close(telnetd_state_t *s)
 {
-	s->state = STATE_CLOSE;
+	s->state = TELNET_STATE_CLOSE;
 }
 
 static void sendopt(telnetd_state_t *s, u8_t code, u8_t option)
@@ -431,59 +433,61 @@ static void newdata(telnetd_state_t *s)
 
 	c = s->buf[s->bufptr];
 	switch(s->state) {
-	case STATE_IAC:
+	case TELNET_STATE_IAC:
 		switch (c) {
 		case TELNET_IAC:
-			s->state = STATE_NORMAL;
+			s->state = TELNET_STATE_NORMAL;
 			break;
 		case TELNET_WILL:
 		case TELNET_WONT:
 		case TELNET_DO:
 		case TELNET_DONT:
 			s->code = c;
-			s->state = STATE_OPT;
+			s->state = TELNET_STATE_OPT;
 			break;
 		case TELNET_SB:
-			s->state = STATE_SB;
+			s->state = TELNET_STATE_SB;
 			break;
 		default:
-			s->state = STATE_NORMAL;
+			s->state = TELNET_STATE_NORMAL;
 			break;
 		}
 		break;
-	case STATE_OPT:
+	case TELNET_STATE_OPT:
 		parseopt(s, s->code, c);
-		s->state = STATE_NORMAL;
+		s->state = TELNET_STATE_NORMAL;
 		break;
 
-	case STATE_SB:
+	case TELNET_STATE_SB:
 		s->code = c;
 		s->optlen = 0;
-		s->state = STATE_OPTDAT;
+		s->state = TELNET_STATE_OPTDAT;
 		break;
 
-	case STATE_OPTDAT:
+	case TELNET_STATE_OPTDAT:
 		if (c == TELNET_SE && s->optdata[s->optlen-1] == TELNET_IAC) {
 			parseoptdat(s, s->code, s->optdata, (s->optlen-1));
-			s->state = STATE_NORMAL;
-			//s->state = STATE_SE;
+			s->state = TELNET_STATE_NORMAL;
+			//s->state = TELNET_STATE_SE;
 		} else if (s->optlen < sizeof(s->optdata)) {
 			s->optdata[s->optlen++] = c;
 		}
 		break;
 
-	/*case STATE_SE:
+	/*case TELNET_STATE_SE:
 		if (c == TELNET_SE) parseoptdat(s, s->code, s->optdata, s->optlen);
-		s->state = STATE_NORMAL;
+		s->state = TELNET_STATE_NORMAL;
 		break;*/
-	case STATE_NORMAL:
+	case TELNET_STATE_NORMAL:
 		if(c == TELNET_IAC) {
-			s->state = STATE_IAC;
+			s->state = TELNET_STATE_IAC;
 		} else {
 			// incoming user input
 			cli_getchar(s->cli_state, c);
 		}
 		break;
+	default:
+		printf("unexpected telnet state\r\n");
 	}
 }
 
@@ -699,9 +703,10 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
 								if(auth_tlnt_srvr_param[k].active_conn == false && (cli_state = alloc_state())){
 									auth_tlnt_srvr_param[k].active_conn = true;
 									auth_tlnt_srvr_param[k].num_connect = new_sd;
-									auth_tlnt_srvr_param[k].state = STATE_NORMAL;
+									auth_tlnt_srvr_param[k].state = TELNET_STATE_NORMAL;
 									cli_state->num_connect = new_sd;
 									cli_state->send = cli_send;
+									cli_state->state = STATE_NORMAL;
 									auth_tlnt_srvr_param[k].cli_state = cli_state;
 
 									while(recv( new_sd, &auth_tlnt_srvr_param[k].buf[auth_tlnt_srvr_param[k].bufptr], 1,  MSG_DONTWAIT ) > 0){
@@ -792,7 +797,7 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
 					if (lBytes < 0) {
 						if (errno != EWOULDBLOCK){
 							DBG printf("  recv() failed\n");
-							auth_tlnt_srvr_param[cur_cnt].state = STATE_CLOSE;
+							auth_tlnt_srvr_param[cur_cnt].state = TELNET_STATE_CLOSE;
 						}
 					}
 
@@ -800,7 +805,7 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
 					/* closed by the client                       */
 					if (lBytes == 0) {
 						DBG printf("  Connection closed\n");
-						auth_tlnt_srvr_param[cur_cnt].state = STATE_CLOSE;
+						auth_tlnt_srvr_param[cur_cnt].state = TELNET_STATE_CLOSE;
 					}
 
 					/* If the close_conn flag was turned on, we need */
@@ -810,13 +815,13 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
 					/* determining the new maximum descriptor value  */
 					/* based on the bits that are still turned on in */
 					/* the master set.                               */
-					if (auth_tlnt_srvr_param[cur_cnt].state == STATE_CLOSE) {
+					if (auth_tlnt_srvr_param[cur_cnt].state == TELNET_STATE_CLOSE || auth_tlnt_srvr_param[cur_cnt].cli_state->state == STATE_CLOSE) {
 						free_state(auth_tlnt_srvr_param[cur_cnt].cli_state);
 						memset(auth_tlnt_srvr_param[cur_cnt].buf, 0, cmdMAX_INPUT_SIZE);
 						memset(auth_tlnt_srvr_param[cur_cnt].prev_cmd, 0, cmdMAX_INPUT_SIZE);
 						memset(auth_tlnt_srvr_param[cur_cnt].optdata, 0, cmdMAX_INPUT_SIZE);
 						auth_tlnt_srvr_param[cur_cnt].optlen = 0;
-						auth_tlnt_srvr_param[cur_cnt].state = STATE_NORMAL;
+						auth_tlnt_srvr_param[cur_cnt].state = TELNET_STATE_NORMAL;
 						auth_tlnt_srvr_param[cur_cnt].num_connect = 0;
 						auth_tlnt_srvr_param[cur_cnt].active_conn = false;
 						auth_tlnt_srvr_param[cur_cnt].telnet_code_auth = USER;

+ 0 - 5
modules/cli/cli.h

@@ -24,11 +24,6 @@ typedef enum{
 typedef enum {
 	STATE_UNUSED,
 	STATE_NORMAL,
-	STATE_IAC,
-	STATE_OPT,
-	STATE_SB,
-	STATE_OPTDAT,
-	STATE_SE,
 	STATE_CLOSE,
 } conn_state_t;