/*! \brief * Fills the common part (for all contacts) of the info structure */ static inline ucontact_info_t* pack_ci( struct sip_msg* _m, contact_t* _c, unsigned int _e, unsigned int _f, unsigned int _flags) { static ucontact_info_t ci; static str no_ua = str_init("n/a"); static str callid; static str path_received = {0,0}; static str path; static str received = {0,0}; static int received_found; static unsigned int allowed, allow_parsed; static struct sip_msg *m = 0; int_str val; if (_m!=0) { memset( &ci, 0, sizeof(ucontact_info_t)); /* Get callid of the message */ callid = _m->callid->body; trim_trailing(&callid); if (callid.len > CALLID_MAX_SIZE) { rerrno = R_CALLID_LEN; LM_ERR("callid too long\n"); goto error; } ci.callid = &callid; /* Get CSeq number of the message */ if (str2int(&get_cseq(_m)->number, (unsigned int*)&ci.cseq) < 0) { rerrno = R_INV_CSEQ; LM_ERR("failed to convert cseq number\n"); goto error; } /* set received socket */ if ( _flags®_SAVE_SOCKET_FLAG) { ci.sock = get_sock_hdr(_m); if (ci.sock==0) ci.sock = _m->rcv.bind_address; } else { ci.sock = _m->rcv.bind_address; } /* additional info from message */ if (parse_headers(_m, HDR_USERAGENT_F, 0) != -1 && _m->user_agent && _m->user_agent->body.len>0 && _m->user_agent->body.len<UA_MAX_SIZE) { ci.user_agent = &_m->user_agent->body; } else { ci.user_agent = &no_ua; } /* extract Path headers */ if ( _flags®_SAVE_PATH_FLAG ) { if (build_path_vector(_m, &path, &path_received, _flags) < 0) { rerrno = R_PARSE_PATH; goto error; } if (path.len && path.s) { ci.path = &path; /* save in msg too for reply */ if (set_path_vector(_m, &path) < 0) { rerrno = R_PARSE_PATH; goto error; } } } ci.last_modified = act_time; /* set flags */ ci.flags = _f; ci.cflags = getb0flags(); /* get received */ if (path_received.len && path_received.s) { ci.cflags |= ul.nat_flag; ci.received = path_received; } allow_parsed = 0; /* not parsed yet */ received_found = 0; /* not found yet */ m = _m; /* remember the message */ } if(_c!=0) { /* Calculate q value of the contact */ if (calc_contact_q(_c->q, &ci.q) < 0) { rerrno = R_INV_Q; LM_ERR("failed to calculate q\n"); goto error; } /* set expire time */ ci.expires = _e; /* Get methods of contact */ if (_c->methods) { if (parse_methods(&(_c->methods->body), &ci.methods) < 0) { rerrno = R_PARSE; LM_ERR("failed to parse contact methods\n"); goto error; } } else { /* check on Allow hdr */ if (allow_parsed == 0) { if (m && parse_allow( m ) != -1) { allowed = get_allow_methods(m); } else { allowed = ALL_METHODS; } allow_parsed = 1; } ci.methods = allowed; } /* get received */ if (ci.received.len==0) { if (_c->received) { ci.received = _c->received->body; } else { if (received_found==0) { memset(&val, 0, sizeof(int_str)); if (rcv_avp_name>=0 && search_first_avp(rcv_avp_type, rcv_avp_name, &val, 0) && val.s.len > 0) { if (val.s.len>RECEIVED_MAX_SIZE) { rerrno = R_CONTACT_LEN; LM_ERR("received too long\n"); goto error; } received = val.s; } else { received.s = 0; received.len = 0; } received_found = 1; } ci.received = received; } } } return &ci; error: return 0; }
/*! \brief * Fills the common part (for all contacts) of the info structure */ static inline ucontact_info_t* pack_ci( struct sip_msg* _m, contact_t* _c, unsigned int _e, unsigned int _f, int _use_regid) { static ucontact_info_t ci; static str no_ua = str_init("n/a"); static str callid; static str path_received = {0,0}; static str path; static str received = {0,0}; static int received_found; static unsigned int allowed, allow_parsed; static struct sip_msg *m = 0; int_str val; if (_m!=0) { memset( &ci, 0, sizeof(ucontact_info_t)); /* Get callid of the message */ callid = _m->callid->body; trim_trailing(&callid); if (callid.len > CALLID_MAX_SIZE) { rerrno = R_CALLID_LEN; LM_ERR("callid too long\n"); goto error; } ci.callid = &callid; /* Get CSeq number of the message */ if (str2int(&get_cseq(_m)->number, (unsigned int*)&ci.cseq) < 0) { rerrno = R_INV_CSEQ; LM_ERR("failed to convert cseq number\n"); goto error; } /* set received socket */ if (_m->flags&sock_flag) { ci.sock = get_sock_val(_m); if (ci.sock==0) ci.sock = _m->rcv.bind_address; } else { ci.sock = _m->rcv.bind_address; } /* set tcp connection id */ if (_m->rcv.proto==PROTO_TCP || _m->rcv.proto==PROTO_TLS || _m->rcv.proto==PROTO_WS || _m->rcv.proto==PROTO_WSS) { ci.tcpconn_id = _m->rcv.proto_reserved1; } else { ci.tcpconn_id = -1; } /* additional info from message */ if (parse_headers(_m, HDR_USERAGENT_F, 0) != -1 && _m->user_agent && _m->user_agent->body.len>0 && _m->user_agent->body.len<MAX_UA_SIZE) { ci.user_agent = &_m->user_agent->body; } else { ci.user_agent = &no_ua; } /* extract Path headers */ if (path_enabled) { if (build_path_vector(_m, &path, &path_received) < 0) { rerrno = R_PARSE_PATH; goto error; } if (path.len && path.s) { ci.path = &path; if (path_mode != PATH_MODE_OFF) { /* save in msg too for reply */ if (set_path_vector(_m, &path) < 0) { rerrno = R_PARSE_PATH; goto error; } } } } ci.last_modified = act_time; /* set flags */ ci.flags = _f; getbflagsval(0, &ci.cflags); /* get received */ if (path_received.len && path_received.s) { ci.cflags |= ul.nat_flag; ci.received = path_received; } allow_parsed = 0; /* not parsed yet */ received_found = 0; /* not found yet */ m = _m; /* remember the message */ } else { memset( &ci.instance, 0, sizeof(str)); } if(_c!=0) { /* hook uri address - should be more than 'sip:' chars */ if(_c->uri.s!=NULL && _c->uri.len>4) ci.c = &_c->uri; /* Calculate q value of the contact */ if (m && m->id == q_override_msg_id) { ci.q = q_override_value; } else if (calc_contact_q(_c->q, &ci.q) < 0) { rerrno = R_INV_Q; LM_ERR("failed to calculate q\n"); goto error; } /* set expire time */ ci.expires = _e; /* Get methods of contact */ if (_c->methods) { if (parse_methods(&(_c->methods->body), &ci.methods) < 0) { rerrno = R_PARSE; LM_ERR("failed to parse contact methods\n"); goto error; } } else { /* check on Allow hdr */ if (allow_parsed == 0) { if (m && parse_allow( m ) != -1) { allowed = get_allow_methods(m); } else { allowed = ALL_METHODS; } allow_parsed = 1; } ci.methods = allowed; } /* get received */ if (ci.received.len==0) { if (_c->received) { ci.received = _c->received->body; } else { if (received_found==0) { memset(&val, 0, sizeof(int_str)); if (rcv_avp_name.n!=0 && search_first_avp(rcv_avp_type, rcv_avp_name, &val, 0) && val.s.len > 0) { if (val.s.len>RECEIVED_MAX_SIZE) { rerrno = R_CONTACT_LEN; LM_ERR("received too long\n"); goto error; } received = val.s; } else { received.s = 0; received.len = 0; } received_found = 1; } ci.received = received; } } if(_c->instance!=NULL && _c->instance->body.len>0) ci.instance = _c->instance->body; if(_use_regid && _c->instance!=NULL && _c->reg_id!=NULL && _c->reg_id->body.len>0) { if(str2int(&_c->reg_id->body, &ci.reg_id)<0 || ci.reg_id==0) { LM_ERR("invalid reg-id value\n"); goto error; } } if(sruid_next(&_reg_sruid)<0) goto error; ci.ruid = _reg_sruid.uid; LM_DBG("generated ruid is: %.*s\n", ci.ruid.len, ci.ruid.s); } return &ci; error: return 0; }