📄 t_reply.c
字号:
if (is_invite(t)) cancel_uacs(t, cancel_bitmap); /* FR for negative INVITES, WAIT anything else */ /* Call to set_final_timer is embedded in relay_reply to avoid * race conditions when reply is sent out and an ACK to stop retransmissions * comes before retransmission timer is set * * set_final_timer(t); */ } } if (reply_status == RPS_ERROR) goto done; /* update FR/RETR timers on provisional replies */ if (msg_status < 200 && (restart_fr_on_each_reply || ((last_uac_status<msg_status) && ((msg_status >= 180) || (last_uac_status == 0))) ) ) { /* provisional now */ if (is_invite(t)) { /* invite: change FR to longer FR_INV, do not * attempt to restart retransmission any more */ backup_list = set_avp_list(&t->user_avps); if (!fr_inv_avp2timer(&timer)) { DBG("reply_received: FR_INV_TIMER = %d\n", timer); set_timer(&uac->request.fr_timer, FR_INV_TIMER_LIST, &timer); } else { set_timer(& uac->request.fr_timer, FR_INV_TIMER_LIST, 0); } set_avp_list(backup_list); } else { /* non-invite: restart retransmissions (slow now) */ uac->request.retr_list = RT_T2; set_timer(&uac->request.retr_timer, RT_T2, 0); } } /* provisional replies */ done: /* don't try to relay statelessly neither on success * (we forwarded statefully) nor on error; on troubles, * simply do nothing; that will make the other party to * retransmit; hopefuly, we'll then be better off */ return 0;}int t_reply_with_body( struct cell *trans, unsigned int code, char * text, char * body, char * new_header, char * to_tag ){ struct lump_rpl *hdr_lump; struct lump_rpl *body_lump; str s_to_tag; str rpl; int ret; struct bookmark bm; s_to_tag.s = to_tag; if(to_tag) s_to_tag.len = strlen(to_tag); /* mark the transaction as replied */ if (code>=200) set_kr(REQ_RPLD); /* add the lumps for new_header and for body (by bogdan) */ if (new_header && strlen(new_header)) { hdr_lump = add_lump_rpl( trans->uas.request, new_header, strlen(new_header), LUMP_RPL_HDR ); if ( !hdr_lump ) { LOG(L_ERR,"ERROR:tm:t_reply_with_body: cannot add hdr lump\n"); goto error; } } else { hdr_lump = 0; } /* body lump */ if(body && strlen(body)) { body_lump = add_lump_rpl( trans->uas.request, body, strlen(body), LUMP_RPL_BODY ); if (body_lump==0) { LOG(L_ERR,"ERROR:tm:t_reply_with_body: cannot add body lump\n"); goto error_1; } } else { body_lump = 0; } rpl.s = build_res_buf_from_sip_req( code, text, &s_to_tag, trans->uas.request, (unsigned int*)&rpl.len, &bm); /* since the msg (trans->uas.request) is a clone into shm memory, to avoid * memory leak or crashing (lumps are create in private memory) I will * remove the lumps by myself here (bogdan) */ if ( hdr_lump ) { unlink_lump_rpl( trans->uas.request, hdr_lump); free_lump_rpl( hdr_lump ); } if( body_lump ) { unlink_lump_rpl( trans->uas.request, body_lump); free_lump_rpl( body_lump ); } if (rpl.s==0) { LOG(L_ERR,"ERROR:tm:t_reply_with_body: failed in doing " "build_res_buf_from_sip_req()\n"); goto error; } DBG("t_reply_with_body: buffer computed\n"); // frees 'res.s' ... no panic ! ret=_reply_light( trans, rpl.s, rpl.len, code, text, s_to_tag.s, s_to_tag.len, 1 /* lock replies */, &bm ); /* this is ugly hack -- the function caller may wish to continue with * transaction and I unref; however, there is now only one use from * vm/fifo_vm_reply and I'm currently to lazy to export UNREF; -jiri */ UNREF(trans); return ret;error_1: if ( hdr_lump ) { unlink_lump_rpl( trans->uas.request, hdr_lump); free_lump_rpl( hdr_lump ); }error: return -1;}/* Syntax: ":vm_reply:[response file]\n code\n reason\n trans_id\n to_tag\n [new headers]\n \n [Body]\n .\n \n" */int fifo_t_reply( FILE *stream, char *response_file ){ int ret; struct cell *trans; char code[16]; char reason[128]; char trans_id[128]; char new_headers[MAX_HEADER]; char body[MAX_BODY]; char to_tag[128]; str sc; /* code */ str sr; /* reason */ str sti; /* trans_id */ str snh; /* new_headers */ str sb; /* body */ str sttag; /* to-tag */ unsigned int hash_index,label,icode; sc.s=code; sr.s=reason; sti.s=trans_id; snh.s=new_headers; sb.s=body; sttag.s=to_tag; sttag.len=0; /* get the infos from FIFO server */ DBG("DEBUG: fifo_t_reply: ############### begin ##############\n"); if (!read_line(sc.s, 16, stream, &sc.len)||sc.len==0) { LOG(L_ERR, "ERROR: fifo_t_reply: code expected\n"); fifo_reply(response_file, "400 fifo_t_reply: code expected"); return -1; } icode = str2s(sc.s,sc.len,&ret); if(ret){ LOG(L_ERR, "ERROR: fifo_t_reply: code(int) has wrong format\n"); fifo_reply(response_file, "400 fifo_t_reply: code(int) has" " wrong format"); return -1; } if(!read_line(sr.s, 128, stream, &sr.len)||sr.len==0){ LOG(L_ERR, "ERROR: fifo_t_reply: reason expected\n"); fifo_reply(response_file, "400 fifo_t_reply: reason expected"); return -1; } sr.s[sr.len]='\0'; if (!read_line(sti.s, 128, stream, &sti.len)||sti.len==0) { LOG(L_ERR, "ERROR: fifo_t_reply: trans_id expected\n"); fifo_reply(response_file, "400 fifo_t_reply: trans_id expected"); return -1; } sti.s[sti.len]='\0'; DBG("DEBUG: fifo_t_reply: trans_id=%.*s\n",sti.len,sti.s); if(sscanf(sti.s,"%u:%u", &hash_index, &label) != 2){ LOG(L_ERR, "ERROR: fifo_t_reply: invalid trans_id (%s)\n",sti.s); fifo_reply(response_file, "400 fifo_t_reply: invalid trans_id"); return -1; } DBG("DEBUG: fifo_t_reply: hash_index=%u label=%u\n",hash_index,label); if( !read_line(sttag.s,64,stream,&sttag.len) || sttag.len==0 ){ LOG(L_ERR, "ERROR: fifo_t_reply: to-tag expected\n"); fifo_reply(response_file, "400 fifo_t_reply: to-ta expected"); return -1; } sttag.s[sttag.len]='\0'; DBG("DEBUG: fifo_t_reply: to-tag: %.*s\n",sttag.len,sttag.s); /* read the new headers */ if (!read_line_set(snh.s, MAX_HEADER, stream, &snh.len)) { LOG(L_ERR, "ERROR: fifo_t_reply: while reading new headers\n"); fifo_reply(response_file, "400 fifo_t_reply: while reading " "new headers"); return -1; } snh.s[snh.len]='\0'; DBG("DEBUG: fifo_t_reply: new headers: %.*s\n", snh.len, snh.s); /* body can be empty ... */ read_body(sb.s, MAX_BODY, stream, &sb.len); sb.s[sb.len]='\0'; DBG("DEBUG: fifo_t_reply: body: <%.*s>\n", sb.len, sb.s); if( t_lookup_ident(&trans,hash_index,label)<0 ) { LOG(L_ERR,"ERROR: fifo_t_reply: lookup failed\n"); fifo_reply(response_file, "481 fifo_t_reply: no such transaction"); return -1; } /* it's refcounted now, t_reply_with body unrefs for me -- I can * continue but may not use T anymore */ ret = t_reply_with_body(trans,icode,reason,body,new_headers,to_tag); if (ret<0) { LOG(L_ERR, "ERROR: fifo_t_reply: reply failed\n"); fifo_reply(response_file, "500 fifo_t_reply: reply failed"); return -1; } fifo_reply(response_file, "200 fifo_t_reply succeeded\n"); DBG("DEBUG: fifo_t_reply: ################ end ##############\n"); return 1;}static int parse_transid(str* s, unsigned int* index, unsigned int* label){ char* buf; if (!s || !index || !label) { LOG(L_ERR, "parse_transid: Invalid parameter value\n"); return -1; } buf = (char*)pkg_malloc(s->len + 1); if (!buf) { LOG(L_ERR, "parse_transid: No memory left\n"); return -1; } memcpy(buf, s->s, s->len + 1); buf[s->len] = '\0'; if (sscanf(buf, "%u:%u", index, label) != 2) { LOG(L_ERR, "parse_transid: Invalid trans_id (%s)\n", buf); pkg_free(buf); return -1; } DBG("parse_transid: hash_index=%u label=%u\n", *index, *label); pkg_free(buf); return 0;}static int send_reply(struct cell *trans, unsigned int code, str* text, str* body, str* headers, str* to_tag){ struct lump_rpl *hdr_lump, *body_lump; str rpl; int ret; struct bookmark bm; /* mark the transaction as replied */ if (code >= 200) set_kr(REQ_RPLD); /* add the lumps for new_header and for body (by bogdan) */ if (headers && headers->len) { hdr_lump = add_lump_rpl(trans->uas.request, headers->s, headers->len, LUMP_RPL_HDR); if (!hdr_lump) { LOG(L_ERR, "send_reply: cannot add hdr lump\n"); goto sr_error; } } else { hdr_lump = 0; } /* body lump */ if (body && body->len) { body_lump = add_lump_rpl(trans->uas.request, body->s, body->len, LUMP_RPL_BODY); if (body_lump == 0) { LOG(L_ERR,"send_reply: cannot add body lump\n"); goto sr_error_1; } } else { body_lump = 0; } /* We can safely zero-terminate the text here, because it is followed * by next line in the received message */ text->s[text->len] = '\0'; rpl.s = build_res_buf_from_sip_req(code, text->s, to_tag, trans->uas.request, (unsigned int*)&rpl.len, &bm); /* since the msg (trans->uas.request) is a clone into shm memory, to avoid * memory leak or crashing (lumps are create in private memory) I will * remove the lumps by myself here (bogdan) */ if (hdr_lump) { unlink_lump_rpl(trans->uas.request, hdr_lump); free_lump_rpl(hdr_lump); } if (body_lump) { unlink_lump_rpl(trans->uas.request, body_lump); free_lump_rpl(body_lump); } if (rpl.s == 0) { LOG(L_ERR,"send_reply: failed in build_res_buf_from_sip_req\n"); goto sr_error; } ret = _reply_light(trans, rpl.s, rpl.len, code, text->s, to_tag->s, to_tag->len, 1 /* lock replies */, &bm); /* this is ugly hack -- the function caller may wish to continue with * transaction and I unref; however, there is now only one use from * vm/fifo_vm_reply and I'm currently to lazy to export UNREF; -jiri */ UNREF(trans); return ret; sr_error_1: if (hdr_lump) { unlink_lump_rpl(trans->uas.request, hdr_lump); free_lump_rpl(hdr_lump); } sr_error: return -1;}int unixsock_t_reply(str* msg){ int ret; struct cell *trans; static char new_headers[MAX_HEADER]; str code, reason, transid, headers, body, to_tag; unsigned int hash_index, label, icode; headers.s = new_headers; headers.len = MAX_HEADER; if (unixsock_read_line(&code, msg) != 0) { unixsock_reply_asciiz("400 Reason code expected\n"); goto err; } icode = str2s(code.s, code.len, &ret); if (ret) { unixsock_reply_printf("400 Reason code has wrong format\n"); goto err; } if (unixsock_read_line(&reason, msg) != 0) { unixsock_reply_asciiz("400 Reason phrase expected\n"); goto err; } if (unixsock_read_line(&transid, msg) != 0) { unixsock_reply_asciiz("400 Transaction ID expected\n"); goto err; } if (parse_transid(&transid, &hash_index, &label) < 0) { unixsock_reply_asciiz("400 Error while parsing transaction ID\n"); goto err; } if (unixsock_read_line(&to_tag, msg) != 0) { unixsock_reply_asciiz("400 To tag expected\n"); goto err; } /* read the new headers */ if (unixsock_read_lineset(&headers, msg) < 0) { unixsock_reply_asciiz("400 Error while reading new headers\n"); goto err; } DBG("lineset: %.*s\n", headers.len, headers.s); /* body can be empty ... */ if (unixsock_read_body(&body, msg) < 0) { unixsock_reply_asciiz("400 Error while reading body\n"); goto err; } DBG("body: %.*s\n", body.len, body.s); if (t_lookup_ident(&trans, hash_index, label) < 0) { LOG(L_ERR,"unixsock_t_reply: lookup failed\n"); unixsock_reply_asciiz("481 No such transaction\n"); goto err; } /* it's refcounted now, t_reply_with body unrefs for me -- I can * continue but may not use T anymore */ ret = send_reply(trans, icode, &reason, &body, &headers, &to_tag); if (ret < 0) { LOG(L_ERR, "unixsock_t_reply: reply failed\n"); unixsock_reply_asciiz("500 Reply failed\n"); goto err; } unixsock_reply_asciiz("200 Succeeded\n"); unixsock_reply_send(); return 1; err: unixsock_reply_send(); return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -