📄 sip_itf.c
字号:
if (sip_msg_info->is_request && dialog == NULL) { dialog = (sip_dialog_t)sip_seed_dialog(obj, sip_msg, sip_ulp_dlg_del, dlg_on_fork, SIP_UAC_DIALOG); } else if (dialog != NULL && (!sip_msg_info->is_request || sip_msg_info->sip_req_method == NOTIFY)) { (void) sip_update_dialog(dialog, _sip_msg, sip_ulp_dlg_del); } } if ((ret = sip_stack_send(obj, _sip_msg->sip_msg_buf, _sip_msg->sip_msg_len)) != 0) { if (sip_trans != NULL) { sip_xaction_terminate(sip_trans, _sip_msg, sip_conn_transport(obj)); } sip_refrele_conn(obj); return (ret); } sip_refrele_conn(obj); return (ret);}/* * Given a response, check if the sent-by in the VIA header is valid. */boolean_tsip_valid_sent_by(sip_msg_t sip_msg){ sip_header_t via; sip_header_value_t value = NULL; int error; const sip_str_t *sent_by = NULL; via = (sip_header_t)sip_get_header(sip_msg, SIP_VIA, NULL, &error); if (via == NULL || error != 0) return (B_TRUE); value = (sip_header_value_t)sip_get_header_value(via, &error); if (value == NULL || error != 0) return (B_TRUE); sent_by = sip_get_via_sent_by_host(value, &error); if (sent_by == NULL || error != 0) return (B_TRUE); if (sip_sent_by_registered(sent_by)) return (B_TRUE); return (B_FALSE);}/* * The receive interface to the transport layer. */voidsip_process_new_packet(sip_conn_object_t conn_object, void *msgstr, size_t msglen){ _sip_msg_t *sip_msg; sip_message_type_t *sip_msg_info; sip_xaction_t *sip_trans; sip_dialog_t dialog = NULL; boolean_t dialog_created = B_FALSE; int transport; char *msgbuf = NULL; sip_refhold_conn(conn_object); transport = sip_conn_transport(conn_object); if (transport == IPPROTO_TCP) {next_msg: msgstr = (char *)sip_get_tcp_msg(conn_object, (char *)msgstr, &msglen); if (msgstr == NULL) { sip_refrele_conn(conn_object); return; } } else { msgbuf = (char *)malloc(msglen + 1); if (msgbuf == NULL) { sip_refrele_conn(conn_object); return; } (void) strncpy(msgbuf, msgstr, msglen); msgbuf[msglen] = '\0'; msgstr = msgbuf; } sip_msg = (_sip_msg_t *)sip_new_msg(); if (sip_msg == NULL) { if (msgbuf != NULL) free(msgbuf); sip_refrele_conn(conn_object); return; } sip_msg->sip_msg_buf = (char *)msgstr; sip_msg->sip_msg_len = msglen; (void) pthread_mutex_lock(&sip_msg->sip_msg_mutex); if (sip_setup_header_pointers(sip_msg) != 0) { (void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex); sip_refrele_conn(conn_object); sip_free_msg((sip_msg_t)sip_msg); return; } if (sip_parse_first_line(sip_msg->sip_msg_start_line, &sip_msg->sip_msg_req_res)) { (void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex); sip_refrele_conn(conn_object); sip_free_msg((sip_msg_t)sip_msg); return; } sip_msg_info = sip_msg->sip_msg_req_res; (void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex); if (sip_check_common_headers(conn_object, sip_msg)) { sip_refrele_conn(conn_object); sip_free_msg((sip_msg_t)sip_msg); return; } /* * Silently discard the response if the top VIA has a sent-by value AND * the UA has registered sent-by values AND the one in the VIA is * not part of the registerd sent-by values. */ if (!sip_msg_info->is_request && !sip_valid_sent_by(sip_msg)) { sip_refrele_conn(conn_object); sip_free_msg((sip_msg_t)sip_msg); return; } sip_trans = (sip_xaction_t *)sip_xaction_get(conn_object, (sip_msg_t)sip_msg, B_FALSE, sip_msg_info->is_request ? SIP_SERVER_TRANSACTION : SIP_CLIENT_TRANSACTION, NULL); if (sip_trans != NULL) { if (sip_xaction_input(conn_object, sip_trans, &sip_msg) != 0) { SIP_XACTION_REFCNT_DECR(sip_trans); sip_refrele_conn(conn_object); sip_free_msg((sip_msg_t)sip_msg); return; } SIP_XACTION_REFCNT_DECR(sip_trans); /* msg was retransmission - handled by the transaction */ if (sip_msg == NULL) goto check_next; } if (sip_manage_dialog) { dialog = sip_dialog_find(sip_msg); if (dialog == NULL) { if (sip_msg_info->is_request) { /* * sip_seed_dialog will check for the * method in the request */ dialog = (sip_dialog_t)sip_seed_dialog( conn_object, sip_msg, sip_ulp_dlg_del, B_FALSE, SIP_UAS_DIALOG); } else { dialog = sip_dialog_create(sip_msg, NULL, SIP_UAC_DIALOG); } dialog_created = B_TRUE; } else if (sip_incomplete_dialog(dialog) && (!sip_msg_info->is_request || sip_msg_info->sip_req_method == NOTIFY)) { dialog = sip_update_dialog(dialog, sip_msg, sip_ulp_dlg_del); } else if (sip_dialog_process(sip_msg, &dialog, sip_ulp_dlg_del) != 0) { if (dialog != NULL) sip_release_dialog(dialog); sip_refrele_conn(conn_object); sip_free_msg((sip_msg_t)sip_msg); return; } } sip_ulp_recv(conn_object, (sip_msg_t)sip_msg, dialog); sip_free_msg((sip_msg_t)sip_msg); if (dialog != NULL && !dialog_created) sip_release_dialog(dialog);check_next: /* * Check if there are more complete messages in the TCP fragment list * to be consumed */ if (transport == IPPROTO_TCP) { msgstr = NULL; msglen = 0; goto next_msg; } sip_refrele_conn(conn_object);}/* * Initialize the stack. The connection manager functions, upper layer * receive functions are mandatory. */intsip_stack_init(sip_stack_init_t *stack_val){#ifdef __linux__ struct timespec tspec;#endif /* If the stack has already been configured, return error */ if (sip_stack_send != NULL || stack_val->sip_version != SIP_STACK_VERSION) { return (EINVAL); } if (stack_val->sip_io_pointers == NULL || stack_val->sip_ulp_pointers == NULL) { return (EINVAL); } sip_ulp_recv = stack_val->sip_ulp_pointers->sip_ulp_recv; sip_manage_dialog = stack_val->sip_stack_flags & SIP_STACK_DIALOGS; sip_stack_send = stack_val->sip_io_pointers->sip_conn_send; sip_refhold_conn = stack_val->sip_io_pointers->sip_hold_conn_object; sip_refrele_conn = stack_val->sip_io_pointers->sip_rel_conn_object; sip_is_conn_stream = stack_val->sip_io_pointers->sip_conn_is_stream; sip_is_conn_reliable = stack_val->sip_io_pointers->sip_conn_is_reliable; sip_conn_rem_addr = stack_val->sip_io_pointers->sip_conn_remote_address; sip_conn_local_addr = stack_val->sip_io_pointers->sip_conn_local_address; sip_conn_transport = stack_val->sip_io_pointers->sip_conn_transport; sip_header_function_table_external = stack_val->sip_function_table; if (sip_ulp_recv == NULL || sip_stack_send == NULL || sip_refhold_conn == NULL || sip_refrele_conn == NULL || sip_is_conn_stream == NULL || sip_is_conn_reliable == NULL || sip_conn_rem_addr == NULL || sip_conn_local_addr == NULL || sip_conn_transport == NULL) { err_ret: sip_ulp_recv = NULL; sip_stack_send = NULL; sip_refhold_conn = NULL; sip_refrele_conn = NULL; sip_is_conn_stream = NULL; sip_is_conn_reliable = NULL; sip_conn_rem_addr = NULL; sip_conn_local_addr = NULL; sip_conn_transport = NULL; sip_header_function_table_external = NULL; sip_stack_timeout = NULL; sip_stack_untimeout = NULL; return (EINVAL); } sip_conn_timer1 = stack_val->sip_io_pointers->sip_conn_timer1; sip_conn_timer2 = stack_val->sip_io_pointers->sip_conn_timer2; sip_conn_timer4 = stack_val->sip_io_pointers->sip_conn_timer4; sip_conn_timerd = stack_val->sip_io_pointers->sip_conn_timerd; /* Use Appln timeout routines, if provided */ if (stack_val->sip_ulp_pointers->sip_ulp_timeout != NULL) { if (stack_val->sip_ulp_pointers->sip_ulp_untimeout == NULL) goto err_ret; sip_stack_timeout = stack_val->sip_ulp_pointers->sip_ulp_timeout; sip_stack_untimeout = stack_val->sip_ulp_pointers->sip_ulp_untimeout; } else { if (stack_val->sip_ulp_pointers->sip_ulp_untimeout != NULL) goto err_ret; sip_timeout_init(); sip_stack_timeout = sip_timeout; sip_stack_untimeout = sip_untimeout; } /* Manage Dialogs? */ if (sip_manage_dialog) { if (stack_val->sip_ulp_pointers->sip_ulp_dlg_del != NULL) { sip_ulp_dlg_del = stack_val->sip_ulp_pointers->sip_ulp_dlg_del; } sip_dialog_init( stack_val->sip_ulp_pointers->sip_ulp_dlg_state_cb); } sip_xaction_init(stack_val->sip_ulp_pointers->sip_ulp_trans_error, stack_val->sip_ulp_pointers->sip_ulp_trans_state_cb);#ifdef __linux__ if (clock_gettime(CLOCK_REALTIME, &tspec) != 0) goto err_ret; sip_hash_salt = tspec.tv_nsec;#else sip_hash_salt = gethrtime();#endif (void) pthread_mutex_init(&sip_sent_by_lock, NULL); return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -