1int receive_msg(char *buf, unsigned int len, receive_info_t *rcv_info) {
 2	if(parse_msg(buf, len, msg) != 0) {
 3		errsipmsg = 1;
 4		evp.data = (void *)msg;
 5
 6        // note: 这里尝试查找并执行nosip模块的 event_route[nosip:msg]事件路由
 7        // 一般情况下,如果没有找到,那么ret的值是-1
 8        // 那么这里的if内部不会执行
 9		if((ret = sr_event_exec(SREV_RCV_NOSIP, &evp)) < NONSIP_MSG_DROP) {
10			LM_DBG("attempt of nonsip message processing failed\n");
11		} else if(ret == NONSIP_MSG_DROP) {
12            // 这里也不会执行
13			LM_DBG("nonsip message processing completed\n");
14			goto end;
15		}
16	}
17
18    // 由于在上面的判断里errsipmsg被设置成1,所以这里的if条件成立
19    if(errsipmsg == 1) {
20        // 打印报错信息,并执行核心错误处理
21		LOG(cfg_get(core, core_cfg, sip_parser_log),
22				"core parsing of SIP message failed (%s:%d/%d)\n",
23				ip_addr2a(&msg->rcv.src_ip), (int)msg->rcv.src_port,
24				(int)msg->rcv.proto);
25		sr_core_ert_run(msg, SR_CORE_ERT_RECEIVE_PARSE_ERROR);
26
27        // 跳转到error02标签,执行后续的清理工作
28		goto error02;
29	}
30
31// 跳转到error02标签,执行后续的清理工作
32error02:
33	free_sip_msg(msg);
34	pkg_free(msg);
35error00:
36	ksr_msg_env_reset();
37	/* reset log prefix */
38	log_prefix_set(NULL);
39
40    // 返回-1,表示出错
41	return -1;
42}
  • 如果调用receive_msg返回负数,那么从调用栈向上查找receive_tcp_msg函数也会返回负数
    • int receive_tcp_msg(char *tcpbuf, unsigned int len,struct receive_info *rcv_info, struct tcp_connection *con)
  • receive_tcp_msg函数返回负数,那么向上查找,tcp_read_req也会返回负数
    • int tcp_read_req(struct tcp_connection *con, int *bytes_read,rd_conn_flags_t *read_flags)
  • tcp_read_req返回负数
    • inline static int handle_io(struct fd_map *fm, short events, int idx)在这个函数内部
		if(unlikely(bytes < 0)) {
			LOG(cfg_get(core, core_cfg, corelog),
					"ERROR: tcp_read_req: error reading - c: %p r: %p (%d)\n",
					con, req, bytes);
			resp = CONN_ERROR;
			goto end_req;
		}

        resp = tcp_read_req(con, &n, &read_flags);
			if(unlikely(resp < 0)) {
				/* some error occurred, but on the new fd, not on the tcp
				 * main fd, so keep the ret value */
				if(unlikely(resp != CONN_EOF))
					con->state = S_CONN_BAD;
				release_tcpconn(con, resp, tcpmain_sock);
				break;
        }

整个调用链条是这样的: handle_io -> tcp_read_req -> receive_tcp_msg -> receive_msg

也就是说,如果没有设置事件路由event_route[nosip:msg]。很大可能基于TCP的链接会主动被kamailio关闭。这样做是安全考量,因为如果kamailio无法解析SIP包,那么它可能不是一个合法的SIP消息。这个行为可以防止恶意用户发送非SIP消息来占用服务器资源。