uac_unixsock.c
来自「性能优秀的SIP Proxy」· C语言 代码 · 共 624 行 · 第 1/2 页
C
624 行
continue; default: /* no valid substitution char -- keep going */ p -= frag_len + 1; needle = d; } } /* possible substitute */ } /* substitution loop */ DBG("get_hfblock: one more hf processed\n"); } /* header loop */ /* construct a single header block now */ ret = pkg_malloc(total_len); if (!ret) { LOG(L_ERR, "get_hfblock: no pkg mem for hf block\n"); goto error; } i = sl.next; dst = ret; while(i) { foo = i; i = i->next; memcpy(dst, foo->s.s, foo->s.len); dst += foo->s.len; pkg_free(foo); } *l = total_len; return ret; error: i = sl.next; while(i) { foo = i; i = i->next; pkg_free(foo); } *l = 0; return 0;}#define FIFO_ROUTE_PREFIX "Route: "#define FIFO_ROUTE_SEPARATOR ", "static void print_routes(dlg_t* _d){ rr_t* ptr; ptr = _d->hooks.first_route; if (ptr) { unixsock_reply_asciiz(FIFO_ROUTE_PREFIX); } else { unixsock_reply_asciiz(".\n"); return; } while(ptr) { unixsock_reply_printf("%.*s", ptr->len, ptr->nameaddr.name.s); ptr = ptr->next; if (ptr) { unixsock_reply_asciiz(FIFO_ROUTE_SEPARATOR); } } if (_d->hooks.last_route) { unixsock_reply_asciiz(FIFO_ROUTE_SEPARATOR "<"); unixsock_reply_printf("%.*s", _d->hooks.last_route->len, _d->hooks.last_route->s); unixsock_reply_asciiz(">"); } if (_d->hooks.first_route) { unixsock_reply_asciiz(CRLF); }}static int print_uris(struct sip_msg* reply){ dlg_t* dlg; dlg = (dlg_t*)shm_malloc(sizeof(dlg_t)); if (!dlg) { LOG(L_ERR, "print_uris: No memory left\n"); return -1; } memset(dlg, 0, sizeof(dlg_t)); if (dlg_response_uac(dlg, reply) < 0) { LOG(L_ERR, "print_uris: Error while creating dialog structure\n"); free_dlg(dlg); return -2; } if (dlg->state != DLG_CONFIRMED) { unixsock_reply_asciiz(".\n.\n.\n"); free_dlg(dlg); return 0; } if (dlg->hooks.request_uri->s) { unixsock_reply_printf("%.*s\n", dlg->hooks.request_uri->len, dlg->hooks.request_uri->s); } else { unixsock_reply_asciiz(".\n"); } if (dlg->hooks.next_hop->s) { unixsock_reply_printf("%.*s\n", dlg->hooks.next_hop->len, dlg->hooks.next_hop->s); } else { unixsock_reply_asciiz(".\n"); } print_routes(dlg); free_dlg(dlg); return 0;}static int new_uac_cb_param(struct uac_cb_param** param, struct sip_msg* msg, struct sockaddr_un* addr){ int len; struct uac_cb_param* p_param; if (!msg || !addr) { param = 0; return 0; } len = msg->from->len; len += msg->callid->len; len += msg->cseq->len; *param = shm_malloc( sizeof(struct uac_cb_param) + len ); if (!*param) { unixsock_reply_asciiz("500 No shared memory"); return -1; } p_param = *param; p_param->from.s = (char*)((*param)+1); memcpy(p_param->from.s,msg->from->name.s,msg->from->len); p_param->from.len = msg->from->len; p_param->callid.s = p_param->from.s + p_param->from.len; memcpy(p_param->callid.s,msg->callid->name.s,msg->callid->len); p_param->callid.len = msg->callid->len; p_param->cseq.s = p_param->callid.s + p_param->callid.len; memcpy(p_param->cseq.s,msg->cseq->name.s,msg->cseq->len); p_param->cseq.len = msg->cseq->len; memcpy(&(p_param->addr), addr, sizeof(struct sockaddr_un)); return 0;}static void free_uac_cb_param(struct uac_cb_param* param){ shm_free(param);}static void callback(struct cell *t, int type, struct tmcb_params *ps){ struct sockaddr_un* to; struct uac_cb_param* param=0; str text; if (!*ps->param) { LOG(L_INFO, "INFO: fifo UAC completed with status %d\n", ps->code); return; } param = (struct uac_cb_param*)(*ps->param); to = ¶m->addr; unixsock_reply_reset(); if (ps->rpl == FAKED_REPLY) { get_reply_status(&text, ps->rpl, ps->code); if (text.s == 0) { LOG(L_ERR, "callback: get_reply_status failed\n"); unixsock_reply_asciiz("500 callback: get_reply_status failed\n"); goto done; } unixsock_reply_printf("%.*s\n.\n.\n.\n", text.len, text.s); unixsock_reply_printf("%.*s", param->from.len, param->from.s); unixsock_reply_printf("%.*s", param->callid.len, param->callid.s); unixsock_reply_printf("%.*s\n", param->cseq.len, param->cseq.s); pkg_free(text.s); } else { text.s = ps->rpl->first_line.u.reply.reason.s; text.len = ps->rpl->first_line.u.reply.reason.len; /* FIXME: check for return values here */ unixsock_reply_printf("%d %.*s\n", ps->rpl->first_line.u.reply.statuscode, text.len, text.s); print_uris(ps->rpl); unixsock_reply_printf("%s\n", ps->rpl->headers->name.s); }done: unixsock_reply_sendto(to); if (ps->code >= 200) { free_uac_cb_param(param); *ps->param=0; /* 0 it so the callback won't do anything if called for a retransmission */ }}int unixsock_uac(str* msg){ str method, ruri, nexthop, headers, body, hfb, callid; struct sip_uri puri, pnexthop; struct sip_msg faked_msg; int ret, sip_error, err_ret, fromtag, cseq_is, cseq; char err_buf[MAX_REASON_LEN]; struct uac_cb_param* shm_param; dlg_t dlg; if (get_method(&method, msg) < 0) return -1; if (get_ruri(&ruri, &puri, msg) < 0) return -1; if (get_nexthop(&nexthop, &pnexthop, msg) < 0) return -1; if (get_headers(&headers, msg) < 0) return -1; /* use SIP parser to look at what is in the FIFO request */ memset(&faked_msg, 0, sizeof(struct sip_msg)); faked_msg.len = headers.len; faked_msg.buf = faked_msg.unparsed = headers.s; if (parse_headers(&faked_msg, HDR_EOH_F, 0) == -1 ) { unixsock_reply_asciiz("400 HFs unparsable\n"); unixsock_reply_send(); goto error; } if (get_body_lines(&body, msg) < 0) goto error; /* at this moment, we collected all the things we got, let's * verify user has not forgotten something */ if (check_msg(&faked_msg, &method, &body, &fromtag, &cseq_is, &cseq, &callid) < 0) goto error; hfb.s = get_hfblock(nexthop.len ? &nexthop : &ruri, faked_msg.headers, &hfb.len, PROTO_UDP); if (!hfb.s) { unixsock_reply_asciiz("500 No memory for HF block"); unixsock_reply_send(); goto error; } memset(&dlg, 0, sizeof(dlg_t)); /* Fill in Call-ID, use given Call-ID if * present and generate it if not present */ if (callid.s && callid.len) dlg.id.call_id = callid; else generate_callid(&dlg.id.call_id); /* We will not fill in dlg->id.rem_tag because * if present it will be printed within To HF */ /* Generate fromtag if not present */ if (!fromtag) { generate_fromtag(&dlg.id.loc_tag, &dlg.id.call_id); } /* Fill in CSeq */ if (cseq_is) dlg.loc_seq.value = cseq; else dlg.loc_seq.value = DEFAULT_CSEQ; dlg.loc_seq.is_set = 1; dlg.loc_uri = faked_msg.from->body; dlg.rem_uri = faked_msg.to->body; dlg.hooks.request_uri = &ruri; dlg.hooks.next_hop = (nexthop.len ? &nexthop : &ruri); shm_param = 0; if ( new_uac_cb_param(&shm_param,&faked_msg,unixsock_sender_addr())< 0) { unixsock_reply_send(); goto error01; } /* we got it all, initiate transaction now! */ ret = t_uac(&method, &hfb, &body, &dlg, callback, shm_param); if (ret <= 0) { err_ret = err2reason_phrase(ret, &sip_error, err_buf, sizeof(err_buf), "FIFO/UAC"); if (err_ret > 0) { unixsock_reply_printf("%d %s", sip_error, err_buf); } else { unixsock_reply_asciiz("500 UNIXSOCK/UAC error"); } unixsock_reply_send(); free_uac_cb_param(shm_param); goto error01; } /* Do not free shm_sockaddr here, it will be used * by the callback */ pkg_free(hfb.s); if (faked_msg.headers) free_hdr_field_lst(faked_msg.headers); return 0; error01: pkg_free(hfb.s);error: if (faked_msg.headers) free_hdr_field_lst(faked_msg.headers); return -1;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?