Browse code

tcpops: added tcp_close_connection([conid])

- close connection for current sip message or by conid

Daniel-Constantin Mierla authored on 22/06/2021 17:01:02
Showing 1 changed files
... ...
@@ -39,6 +39,7 @@
39 39
 #include "../../core/mod_fix.h"
40 40
 #include "../../core/events.h"
41 41
 #include "../../core/kemi.h"
42
+#include "../../core/pass_fd.h"
42 43
 
43 44
 #include "tcpops.h"
44 45
 
... ...
@@ -63,6 +64,8 @@ static int w_tcp_conid_alive(sip_msg_t* msg, char* con, char *p2);
63 64
 static int w_tcp_get_conid(sip_msg_t* msg, char *paddr, char *pvn);
64 65
 static int w_tcp_set_otcpid(sip_msg_t* msg, char* conid, char *p2);
65 66
 static int w_tcp_set_otcpid_flag(sip_msg_t* msg, char* mode, char *p2);
67
+static int w_tcp_close_connection(sip_msg_t* msg, char* p1, char *p2);
68
+static int w_tcp_close_connection_id(sip_msg_t* msg, char* pconid, char *p2);
66 69
 
67 70
 str tcpops_event_callback = STR_NULL;
68 71
 
... ...
@@ -103,6 +106,10 @@ static cmd_export_t cmds[]={
103 106
 			fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
104 107
 	{"tcp_set_otcpid_flag", (cmd_function)w_tcp_set_otcpid_flag, 1,
105 108
 			fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
109
+	{"tcp_close_connection", (cmd_function)w_tcp_close_connection, 0,
110
+			0, 0, ANY_ROUTE},
111
+	{"tcp_close_connection", (cmd_function)w_tcp_close_connection_id, 1,
112
+			fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
106 113
 	{0, 0, 0, 0, 0, 0}
107 114
 };
108 115
 
... ...
@@ -665,6 +672,65 @@ static int w_tcp_set_otcpid_flag(sip_msg_t* msg, char* mode, char *p2)
665 672
 	return ki_tcp_set_otcpid_flag(msg, vmode);
666 673
 }
667 674
 
675
+/*!
676
+ * \brief Close a TCP connection
677
+ *
678
+ * Requests the TCP main process to close the specified TCP connection
679
+ * \param conid the internal connection ID
680
+ */
681
+static int ki_tcp_close_connection_id(sip_msg_t *msg, int conid)
682
+{
683
+	struct tcp_connection *con;
684
+	long mcmd[2];
685
+	int n;
686
+
687
+	if ((con = tcpconn_get(conid, 0, 0, 0, 0))) {
688
+		mcmd[0] = (long)con;
689
+		mcmd[1] = CONN_EOF;
690
+
691
+		con->send_flags.f |= SND_F_CON_CLOSE;
692
+		con->flags |= F_CONN_FORCE_EOF;
693
+
694
+		n = send_all(unix_tcp_sock, mcmd, sizeof(mcmd));
695
+		if (unlikely(n <= 0)){
696
+			LM_ERR("failed to send close request: %s (%d)\n", strerror(errno), errno);
697
+			return -2;
698
+		}
699
+		return 1;
700
+	}
701
+	return -1;
702
+}
703
+
704
+/**
705
+ *
706
+ */
707
+static int ki_tcp_close_connection(sip_msg_t *msg)
708
+{
709
+	return ki_tcp_close_connection_id(msg, msg->rcv.proto_reserved1);
710
+}
711
+
712
+/**
713
+ *
714
+ */
715
+static int w_tcp_close_connection_id(sip_msg_t* msg, char* pconid, char *p2)
716
+{
717
+	int conid = 0;
718
+
719
+	if(fixup_get_ivalue(msg, (gparam_t*)pconid, &conid)<0) {
720
+		LM_ERR("failed to get conid parameter\n");
721
+		return -1;
722
+	}
723
+	return ki_tcp_close_connection_id(msg, conid);
724
+}
725
+
726
+/**
727
+ *
728
+ */
729
+static int w_tcp_close_connection(sip_msg_t* msg, char* p1, char *p2)
730
+{
731
+	return ki_tcp_close_connection_id(msg, msg->rcv.proto_reserved1);
732
+}
733
+
668 734
 /**
669 735
  *
670 736
  */
... ...
@@ -799,6 +865,16 @@ static sr_kemi_t sr_kemi_tcpops_exports[] = {
799 865
 		{ SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
800 866
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
801 867
 	},
868
+	{ str_init("tcpops"), str_init("tcp_close_connection"),
869
+		SR_KEMIP_INT, ki_tcp_close_connection,
870
+		{ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
871
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
872
+	},
873
+	{ str_init("tcpops"), str_init("tcp_close_connection_id"),
874
+		SR_KEMIP_INT, ki_tcp_close_connection_id,
875
+		{ SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
876
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
877
+	},
802 878
 
803 879
 	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
804 880
 };