[mw-devel] [Git][arthur/mw][master] Make the client quit on NONCE mismatch

Justin Mitchell arthur at sucs.org
Wed Jul 20 15:36:00 BST 2016


Justin Mitchell pushed to branch master at Justin Mitchell / mw


Commits:
9bf105a1 by Justin Mitchell at 2016-07-20T15:35:28+01:00
Make the client quit on NONCE mismatch

Needed the server to send an error response instead of immediately
closing, and wait for it to be sent.
also needed certain parts of the client shutdown proceedure tonot
cleanup/free things that hadnt yet been initialised.

- - - - -


9 changed files:

- src/client/hash.c
- src/client/incoming.c
- src/client/js.c
- src/client/script.c
- src/ipc.c
- src/ipc.h
- src/server/servsock.c
- src/server/servsock.h
- src/socket.h


Changes:

=====================================
src/client/hash.c
=====================================
--- a/src/client/hash.c
+++ b/src/client/hash.c
@@ -66,6 +66,9 @@ void hash_free(int field)
 {
     static union fieldrec *frec;
 
+    /* make sure its actually alloced first */
+    if (field == -1) return;
+
     /* Make sure all variables are removed */
     hash_purge(field);
 


=====================================
src/client/incoming.c
=====================================
--- a/src/client/incoming.c
+++ b/src/client/incoming.c
@@ -474,6 +474,21 @@ static void display_uptime(ipc_message_t *msg)
 	json_decref(j);
 }
 
+/** Server sent us an error, usually pretty fatal */
+static void handle_ipc_error(ipc_message_t *msg)
+{
+	json_t * j = json_init(msg);
+	const char * type = json_getstring(j, "error");
+
+	if (strcasecmp(type, "NONCE")==0) {
+		printf("Incompatible server version. Quitting.\n");
+	} else {
+		printf("Undefined server error '%s'\n", type);
+	}
+	json_decref(j);
+	close_down(0, NULL, NULL);
+}
+
 static void display_error(ipc_message_t *msg)
 {
 	json_t * j = json_init(msg);
@@ -754,6 +769,9 @@ static void accept_pipe_cmd(ipc_message_t *msg, struct user *mesg_user)
 		case IPC_WHOLIST:
 			update_wholist(msg);
 			break;
+		case IPC_ERROR:
+			handle_ipc_error(msg);
+			break;
 		default:
 			devel_msg("incoming_mesg", "unknown message type %d.\007", state);
 	}


=====================================
src/client/js.c
=====================================
--- a/src/client/js.c
+++ b/src/client/js.c
@@ -1202,8 +1202,8 @@ int js_isrunning(void)
 // cleans up the javascript environment
 int stop_js(void)
 {
-	JS_DestroyContext(jscx);
-	JS_DestroyRuntime(jsrt);
+	if (jscx != NULL) JS_DestroyContext(jscx);
+	if (jsrt != NULL) JS_DestroyRuntime(jsrt);
 	return 0;
 
 }


=====================================
src/client/script.c
=====================================
--- a/src/client/script.c
+++ b/src/client/script.c
@@ -34,7 +34,7 @@ extern int current_rights;
 
 struct function *function_list=NULL;
 extern const char *autoexec_arg;
-var_list_t var_list;
+var_list_t var_list = -1;
 var_list_t *local_vars=NULL;
 CompStack *comparison_stack=NULL;
 


=====================================
src/ipc.c
=====================================
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -209,6 +209,7 @@ const char * ipc_nametype(enum ipc_types msgtype)
 		case IPC_EVENT: return "IPC_EVENT"; break;
 		case IPC_ACTION: return "IPC_ACTION"; break;
 		case IPC_WHOLIST: return "IPC_WHOLIST"; break;
+		case IPC_ERROR: return "IPC_ERROR"; break;
 	}
 	return "IPC_Unknown";
 }


=====================================
src/ipc.h
=====================================
--- a/src/ipc.h
+++ b/src/ipc.h
@@ -41,6 +41,7 @@ enum ipc_types {
 	IPC_PROTLEVEL	= 24,
 	IPC_PROTPOWER	= 25,
 	IPC_DOING	= 26,
+	IPC_ERROR	= FCC('ERRO'),
 	IPC_HELLO	= FCC('HELO'),
 	IPC_UPTIME	= FCC('UPTM'),
 	IPC_SAYTOROOM	= FCC('SAYR'),
@@ -53,6 +54,11 @@ enum ipc_types {
 	IPC_WHOLIST	= FCC('WHOL')
 };
 
+enum ipc_errors {
+	IPC_ERROR_UNDEFINED,
+	IPC_ERROR_NONCE
+};
+
 #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
 #pragma GCC diagnostic pop
 #endif


=====================================
src/server/servsock.c
=====================================
--- a/src/server/servsock.c
+++ b/src/server/servsock.c
@@ -196,9 +196,14 @@ bodge:
 			struct list_head *pos, *q;
 			list_for_each_safe(pos, q, &connection_list) {
 				ipc_connection_t * c = list_entry(pos, ipc_connection_t, list);
+				/* connections that went bad */
 				if (c->fd != -1 && c->state == IPCSTATE_ERROR) {
 					drop_connection(c);
 				}
+				/* connections with a soft close */
+				if (c->state == IPCSTATE_PURGE && list_empty(&(c->outq))) {
+					drop_connection(c);
+				}
 			}
 		}
 		/* end of events handling, do periodic stuff here */
@@ -284,7 +289,16 @@ void process_msg(ipc_connection_t *conn, ipc_message_t *msg)
 		if (!match_nonce(&msg->body[4])) {
 			printf("Mismatched nonce from fd=%d. dropping.\n", conn->fd);
 			ipcmsg_destroy(msg);
-			drop_connection(conn);
+
+			// tell the client
+			ipc_message_t * error = msg_error("NONCE");
+			ipcmsg_destination(error, conn->addr);
+			msg_attach(error, conn);
+			ipcmsg_destroy(error);
+			printf("Sending error message\n");
+
+			// purge the tx queue and close
+			conn->state = IPCSTATE_PURGE;
 			return;
 		}
 		printf("WHO Add: pid=%d posn=%d\n", conn->addr, conn->user);
@@ -805,3 +819,14 @@ int32_t who_find(const char * username)
 	close(users_fd);
 	return -1;
 }
+
+ipc_message_t * msg_error(const char *type)
+{
+	ipc_message_t * msg = ipcmsg_create(IPC_ERROR, SYSTEM_USER);
+
+	json_t * j = json_init(NULL);
+	json_addstring(j, "error", type);
+	ipcmsg_json_encode(msg, j);
+	json_decref(j);
+	return msg;
+}


=====================================
src/server/servsock.h
=====================================
--- a/src/server/servsock.h
+++ b/src/server/servsock.h
@@ -28,5 +28,6 @@ void send_error(ipc_connection_t *conn, ipc_message_t *orig, const char *format,
 void msg_apply_gag(struct user * from, ipc_message_t * msg, const char * field);
 ipc_message_t * msg_wholist(void);
 int32_t who_find(const char * username);
+ipc_message_t * msg_error(const char *type);
 
 #endif /* SERVSOCK_H */


=====================================
src/socket.h
=====================================
--- a/src/socket.h
+++ b/src/socket.h
@@ -13,10 +13,11 @@
 #define SYSTEM_USER 1
 
 enum ipcsock_state {
-	IPCSTATE_CONNECTED,
-	IPCSTATE_VALID,
-	IPCSTATE_ERROR,
-	IPCSTATE_DELETED
+	IPCSTATE_CONNECTED,  // connected but not running
+	IPCSTATE_VALID,	     // running
+	IPCSTATE_ERROR,	     // error, about to close
+	IPCSTATE_PURGE,      // soft close
+	IPCSTATE_DELETED     // already closed and gone
 };
 
 /* packed struct for socket ipc */



View it on GitLab: https://projects.sucs.org/arthur/mw/commit/9bf105a1380f6ae1a284c2de983296478757ec57
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sucs.org/pipermail/mw-devel/attachments/20160720/34f80eda/attachment-0001.html>


More information about the mw-devel mailing list