Browse code

core: first attempt at event_route for TCP connection close

Peter Dunkley authored on 17/05/2013 23:27:17
Showing 1 changed files
... ...
@@ -152,7 +152,7 @@
152 152
 #endif
153 153
 #include <sys/poll.h>
154 154
 
155
-
155
+#include "dset.h"
156 156
 #include "ip_addr.h"
157 157
 #include "pass_fd.h"
158 158
 #include "tcp_conn.h"
... ...
@@ -3018,6 +3018,55 @@ inline static int tcpconn_chld_put(struct tcp_connection* tcpconn)
3018 3018
 
3019 3019
 
3020 3020
 
3021
+/* Fake message done the "old fashioned" way here so as not to add a dependency
3022
+   on lib/kcore */
3023
+#define FAKED_SIP_MSG "OPTIONS sip:you@kamailio.org SIP/2.0\r\nVia: SIP/2.0/UDP 127.0.0.1\r\nFrom: <you@kamailio.org>;tag=123\r\nTo: <you@kamailio.org>\r\nCall-ID: 123\r\nCSeq: 1 OPTIONS\r\nContent-Length: 0\r\n\r\n"
3024
+#define FAKED_SIP_MSG_LEN (sizeof(FAKED_SIP_MSG)-1)
3025
+static char _faked_sip_msg[FAKED_SIP_MSG_LEN+1];
3026
+static struct sip_msg _faked_msg;
3027
+static unsigned int _faked_msg_no = 0;
3028
+
3029
+inline static void tcp_close_run_route(struct tcp_connection *tcpconn)
3030
+{
3031
+	int rt, backup_rt;
3032
+	struct run_act_ctx ctx;
3033
+
3034
+	WARN("tcp_close_run_route event_route[tcp:closed]\n");
3035
+
3036
+	rt = route_get(&event_rt, "tcp:closed");
3037
+	if (rt < 0 || event_rt.rlist[rt] == NULL)
3038
+		return;
3039
+
3040
+	if (_faked_msg_no == 0) {
3041
+		memcpy(_faked_sip_msg, FAKED_SIP_MSG, FAKED_SIP_MSG_LEN);
3042
+		_faked_sip_msg[FAKED_SIP_MSG_LEN] = 0;
3043
+
3044
+		memset(&_faked_msg, 0, sizeof(struct sip_msg));
3045
+		_faked_msg.buf = _faked_sip_msg;
3046
+		_faked_msg.len = FAKED_SIP_MSG_LEN;
3047
+		_faked_msg.set_global_address = default_global_address;
3048
+		_faked_msg.set_global_port=default_global_port;
3049
+
3050
+		if (parse_msg(_faked_msg.buf, _faked_msg.len,
3051
+					&_faked_msg) != 0) {
3052
+			LM_ERR("parse_msg failed\n");
3053
+			return;
3054
+		}
3055
+	}
3056
+
3057
+	_faked_msg.id = 1 + _faked_msg_no++;
3058
+	_faked_msg.pid = my_pid();
3059
+	memset(&_faked_msg.tval, 0, sizeof(struct timeval));
3060
+	_faked_msg.rcv = tcpconn->rcv;
3061
+	clear_branches();
3062
+	
3063
+	backup_rt = get_route_type();
3064
+	set_route_type(REQUEST_ROUTE);
3065
+	init_run_actions_ctx(&ctx);
3066
+	run_top_route(event_rt.rlist[rt], &_faked_msg, 0);
3067
+	set_route_type(backup_rt);
3068
+}
3069
+
3021 3070
 /* simple destroy function (the connection should be already removed
3022 3071
  * from the hashes. refcnt 0 and the fds should not be watched anymore for IO)
3023 3072
  */
... ...
@@ -3026,6 +3075,9 @@ inline static void tcpconn_destroy(struct tcp_connection* tcpconn)
3026 3026
 		DBG("tcpconn_destroy: destroying connection %p (%d, %d) "
3027 3027
 				"flags %04x\n", tcpconn, tcpconn->id,
3028 3028
 				tcpconn->s, tcpconn->flags);
3029
+
3030
+		tcp_close_run_route(tcpconn);
3031
+
3029 3032
 		if (unlikely(tcpconn->flags & F_CONN_HASHED)){
3030 3033
 			LOG(L_CRIT, "BUG: tcpconn_destroy: called with hashed"
3031 3034
 						" connection (%p)\n", tcpconn);