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消息来占用服务器资源。