/*! * \brief Print contact, for debugging purposes only * \param _f output file * \param _c printed contact */ void print_ucontact(FILE* _f, ucontact_t* _c) { time_t t = time(0); char* st; switch(_c->state) { case CS_NEW: st = "CS_NEW"; break; case CS_SYNC: st = "CS_SYNC"; break; case CS_DIRTY: st = "CS_DIRTY"; break; default: st = "CS_UNKNOWN"; break; } fprintf(_f, "~~~Contact(%p)~~~\n", _c); fprintf(_f, "domain : '%.*s'\n", _c->domain->len, ZSW(_c->domain->s)); fprintf(_f, "aor : '%.*s'\n", _c->aor->len, ZSW(_c->aor->s)); fprintf(_f, "Contact : '%.*s'\n", _c->c.len, ZSW(_c->c.s)); fprintf(_f, "Expires : "); if (_c->expires == 0) { fprintf(_f, "Permanent\n"); } else if (_c->expires == UL_EXPIRED_TIME) { fprintf(_f, "Deleted\n"); } else if (t > _c->expires) { fprintf(_f, "Expired\n"); } else { fprintf(_f, "%u\n", (unsigned int)(_c->expires - t)); } fprintf(_f, "q : %s\n", q2str(_c->q, 0)); fprintf(_f, "Call-ID : '%.*s'\n", _c->callid.len, ZSW(_c->callid.s)); fprintf(_f, "CSeq : %d\n", _c->cseq); fprintf(_f, "User-Agent: '%.*s'\n", _c->user_agent.len, ZSW(_c->user_agent.s)); fprintf(_f, "received : '%.*s'\n", _c->received.len, ZSW(_c->received.s)); fprintf(_f, "Path : '%.*s'\n", _c->path.len, ZSW(_c->path.s)); fprintf(_f, "State : %s\n", st); fprintf(_f, "Flags : %u\n", _c->flags); if (_c->sock) { fprintf(_f, "Sock : %.*s (%p)\n", _c->sock->sock_str.len,_c->sock->sock_str.s,_c->sock); } else { fprintf(_f, "Sock : none (null)\n"); } fprintf(_f, "Methods : %u\n", _c->methods); fprintf(_f, "ruid : '%.*s'\n", _c->ruid.len, ZSW(_c->ruid.s)); fprintf(_f, "instance : '%.*s'\n", _c->instance.len, ZSW(_c->instance.s)); fprintf(_f, "reg-id : %u\n", _c->reg_id); fprintf(_f, "next : %p\n", _c->next); fprintf(_f, "prev : %p\n", _c->prev); fprintf(_f, "~~~/Contact~~~~\n"); }
/*! * \brief Print contact, for debugging purposes only * \param _f output file * \param _c printed contact */ void print_ucontact(FILE* _f, ucontact_t* _c) { time_t t = time(0); char* st = ""; param_t * tmp; fprintf(_f, "~~~Contact(%p)~~~\n", _c); fprintf(_f, "domain : '%.*s'\n", _c->domain.len, ZSW(_c->domain.s)); fprintf(_f, "aor : '%.*s'\n", _c->aor.len, ZSW(_c->aor.s)); fprintf(_f, "Contact : '%.*s'\n", _c->c.len, ZSW(_c->c.s)); fprintf(_f, "Params :\n"); tmp = _c->params; while (tmp) { fprintf(_f, "Param Name: '%.*s' Param Body '%.*s'\n", tmp->name.len, ZSW(tmp->name.s), tmp->body.len, ZSW(tmp->body.s)); tmp = tmp->next; } fprintf(_f, "Expires : "); if (_c->expires == 0) { fprintf(_f, "Permanent\n"); } else if (_c->expires == UL_EXPIRED_TIME) { fprintf(_f, "Deleted\n"); } else if (t > _c->expires) { fprintf(_f, "Expired\n"); } else { fprintf(_f, "%u\n", (unsigned int) (_c->expires - t)); } fprintf(_f, "q : %s\n", q2str(_c->q, 0)); fprintf(_f, "Call-ID : '%.*s'\n", _c->callid.len, ZSW(_c->callid.s)); fprintf(_f, "CSeq : %d\n", _c->cseq); fprintf(_f, "User-Agent: '%.*s'\n", _c->user_agent.len, ZSW(_c->user_agent.s)); fprintf(_f, "received : '%.*s'\n", _c->received.len, ZSW(_c->received.s)); fprintf(_f, "Path : '%.*s'\n", _c->path.len, ZSW(_c->path.s)); fprintf(_f, "State : %s\n", st); fprintf(_f, "Flags : %u\n", _c->flags); if (_c->sock) { fprintf(_f, "Sock : %.*s (%p)\n", _c->sock->sock_str.len, _c->sock->sock_str.s, _c->sock); } else { fprintf(_f, "Sock : none (null)\n"); } fprintf(_f, "Methods : %u\n", _c->methods); fprintf(_f, "next : %p\n", _c->next); fprintf(_f, "prev : %p\n", _c->prev); fprintf(_f, "~~~/Contact~~~~\n"); }
/* * Build Contact HF for reply */ static inline int print_contacts(FILE* _o, ucontact_t* _c) { int cnt = 0; while(_c) { if (VALID_CONTACT(_c, act_time)) { cnt++; if (cnt==1) { fputs( "200 OK\n", _o); } fprintf(_o, "<%.*s>;q=%s;expires=%d\n", _c->c.len, ZSW(_c->c.s), q2str(_c->q, 0), (int)(_c->expires - act_time)); } _c = _c->next; } return cnt; }
/*! \brief * Allocate a memory buffer and print Contact * header fields into it */ int build_contact(sip_msg_t *msg, ucontact_t* c, str *host) { char *p, *cp; char *a; int fl, len; str user; str inst; unsigned int ahash; unsigned short digit; int mode; sr_xavp_t *xavp=NULL; sr_xavp_t *list=NULL; str xname = {"ruid", 4}; sr_xval_t xval; if(msg!=NULL && parse_supported(msg)==0 && (get_supported(msg) & F_OPTION_TAG_GRUU)) mode = 1; else mode = 0; contact.data_len = calc_buf_len(c, host, mode); if (!contact.data_len) return 0; if (!contact.buf || (contact.buf_len < contact.data_len)) { if (contact.buf) pkg_free(contact.buf); contact.buf = (char*)pkg_malloc(contact.data_len); if (!contact.buf) { contact.data_len = 0; contact.buf_len = 0; LM_ERR("no pkg memory left\n"); return -1; } else { contact.buf_len = contact.data_len; } } p = contact.buf; memcpy(p, CONTACT_BEGIN, CONTACT_BEGIN_LEN); p += CONTACT_BEGIN_LEN; /* add xavp with details of the record (ruid, ...) */ if(reg_xavp_rcd.s!=NULL) { list = xavp_get(®_xavp_rcd, NULL); xavp = list; } fl = 0; while(c) { if (VALID_CONTACT(c, act_time)) { if (fl) { memcpy(p, CONTACT_SEP, CONTACT_SEP_LEN); p += CONTACT_SEP_LEN; } else { fl = 1; } *p++ = '<'; memcpy(p, c->c.s, c->c.len); p += c->c.len; *p++ = '>'; len = len_q(c->q); if (len) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; memcpy(p, q2str(c->q, 0), len); p += len; } memcpy(p, EXPIRES_PARAM, EXPIRES_PARAM_LEN); p += EXPIRES_PARAM_LEN; cp = int2str((int)(c->expires - act_time), &len); memcpy(p, cp, len); p += len; if (rcv_param.len>0 && c->received.s) { *p++ = ';'; memcpy(p, rcv_param.s, rcv_param.len); p += rcv_param.len; *p++ = '='; *p++ = '\"'; memcpy(p, c->received.s, c->received.len); p += c->received.len; *p++ = '\"'; } if (reg_gruu_enabled==1 && c->instance.len>0 && mode==1) { user.s = c->aor->s; a = memchr(c->aor->s, '@', c->aor->len); if(a!=NULL) { user.len = a - user.s; } else { user.len = c->aor->len; } /* pub-gruu */ memcpy(p, PUB_GRUU_PARAM, PUB_GRUU_PARAM_LEN); p += PUB_GRUU_PARAM_LEN; *p++ = '\"'; memcpy(p, "sip:", 4); p += 4; if(a!=NULL) { memcpy(p, c->aor->s, c->aor->len); p += c->aor->len; } else { memcpy(p, user.s, user.len); p += user.len; *p++ = '@'; memcpy(p, host->s, host->len); p += host->len; } memcpy(p, GR_PARAM, GR_PARAM_LEN); p += GR_PARAM_LEN; inst = c->instance; if(inst.s[0]=='<' && inst.s[inst.len-1]=='>') { inst.s++; inst.len -= 2; } memcpy(p, inst.s, inst.len); p += inst.len; *p++ = '\"'; /* temp-gruu */ memcpy(p, TMP_GRUU_PARAM, TMP_GRUU_PARAM_LEN); p += TMP_GRUU_PARAM_LEN; *p++ = '\"'; memcpy(p, "sip:", 4); p += 4; memcpy(p, c->ruid.s, c->ruid.len); p += c->ruid.len; *p++ = '-'; ahash = ul.get_aorhash(c->aor); while(ahash!=0) { digit = ahash & 0x0f; *p++ = (digit >= 10) ? digit + 'a' - 10 : digit + '0'; ahash >>= 4; } *p++ = '@'; memcpy(p, host->s, host->len); p += host->len; memcpy(p, GR_PARAM, GR_PARAM_LEN); p += GR_PARAM_LEN - 1; *p++ = '\"'; } if (c->instance.len>0) { /* +sip-instance */ memcpy(p, SIP_INSTANCE_PARAM, SIP_INSTANCE_PARAM_LEN); p += SIP_INSTANCE_PARAM_LEN; *p++ = '\"'; memcpy(p, c->instance.s, c->instance.len); p += c->instance.len; *p++ = '\"'; } if (c->reg_id>0) { /* reg-id */ memcpy(p, REG_ID_PARAM, REG_ID_PARAM_LEN); p += REG_ID_PARAM_LEN; cp = int2str(c->reg_id, &len); memcpy(p, cp, len); p += len; } if(reg_xavp_rcd.s!=NULL) { memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = c->ruid; if(xavp_add_value(&xname, &xval, &xavp)==NULL) { LM_ERR("cannot add ruid value to xavp\n"); } } } c = c->next; }
/* * Create a Contact header field from the dset * array */ char* print_dset(struct sip_msg* msg, int* len) { int cnt, i; unsigned int qlen; qvalue_t q; str uri; char* p, *qbuf; static char dset[MAX_REDIRECTION_LEN]; if (msg->new_uri.s) { cnt = 1; *len = msg->new_uri.len; if (ruri_q != Q_UNSPECIFIED) { *len += 1 + Q_PARAM_LEN + len_q(ruri_q); } } else { cnt = 0; *len = 0; } init_branch_iterator(); while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0))) { cnt++; *len += uri.len; if (q != Q_UNSPECIFIED) { *len += 1 + Q_PARAM_LEN + len_q(q); } } if (cnt == 0) return 0; *len += CONTACT_LEN + CRLF_LEN + (cnt - 1) * CONTACT_DELIM_LEN; if (*len + 1 > MAX_REDIRECTION_LEN) { LOG(L_ERR, "ERROR: redirection buffer length exceed\n"); return 0; } memcpy(dset, CONTACT, CONTACT_LEN); p = dset + CONTACT_LEN; if (msg->new_uri.s) { if (ruri_q != Q_UNSPECIFIED) { *p++ = '<'; } memcpy(p, msg->new_uri.s, msg->new_uri.len); p += msg->new_uri.len; if (ruri_q != Q_UNSPECIFIED) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; qbuf = q2str(ruri_q, &qlen); memcpy(p, qbuf, qlen); p += qlen; } i = 1; } else { i = 0; } init_branch_iterator(); while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0))) { if (i) { memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN); p += CONTACT_DELIM_LEN; } if (q != Q_UNSPECIFIED) { *p++ = '<'; } memcpy(p, uri.s, uri.len); p += uri.len; if (q != Q_UNSPECIFIED) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; qbuf = q2str(q, &qlen); memcpy(p, qbuf, qlen); p += qlen; } i++; } memcpy(p, CRLF " ", CRLF_LEN + 1); return dset; }
/*! \brief * Allocate a memory buffer and print Contact * header fields into it */ int build_contact(ucontact_t* c) { char *p, *cp; int fl, len; contact.data_len = calc_buf_len(c); if (!contact.data_len) return 0; if (!contact.buf || (contact.buf_len < contact.data_len)) { if (contact.buf) pkg_free(contact.buf); contact.buf = (char*)pkg_malloc(contact.data_len); if (!contact.buf) { contact.data_len = 0; contact.buf_len = 0; LM_ERR("no pkg memory left\n"); return -1; } else { contact.buf_len = contact.data_len; } } p = contact.buf; memcpy(p, CONTACT_BEGIN, CONTACT_BEGIN_LEN); p += CONTACT_BEGIN_LEN; fl = 0; while(c) { if (VALID_CONTACT(c, act_time)) { if (fl) { memcpy(p, CONTACT_SEP, CONTACT_SEP_LEN); p += CONTACT_SEP_LEN; } else { fl = 1; } *p++ = '<'; memcpy(p, c->c.s, c->c.len); p += c->c.len; *p++ = '>'; len = len_q(c->q); if (len) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; memcpy(p, q2str(c->q, 0), len); p += len; } memcpy(p, EXPIRES_PARAM, EXPIRES_PARAM_LEN); p += EXPIRES_PARAM_LEN; cp = int2str((int)(c->expires - act_time), &len); memcpy(p, cp, len); p += len; if (c->received.s) { *p++ = ';'; memcpy(p, rcv_param.s, rcv_param.len); p += rcv_param.len; *p++ = '='; *p++ = '\"'; memcpy(p, c->received.s, c->received.len); p += c->received.len; *p++ = '\"'; } } c = c->next; } memcpy(p, CRLF, CRLF_LEN); p += CRLF_LEN; contact.data_len = p - contact.buf; LM_DBG("created Contact HF: %.*s\n", contact.data_len, contact.buf); return 0; }
/*! * \brief Dumps the contacts of an AOR * \param cmd mi_root containing the parameter * \param param not used * \note expects 2 nodes: the table name and the AOR * \return mi_root with the result or 0 on failure */ struct mi_root* mi_usrloc_show_contact(struct mi_root *cmd, void *param) { struct mi_root *rpl_tree; struct mi_node *rpl, *node; udomain_t *dom; urecord_t *rec; ucontact_t* con; str *aor; int ret; node = cmd->node.kids; if (node==NULL || node->next==NULL || node->next->next!=NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); /* look for table */ dom = mi_find_domain( &node->value ); if (dom==NULL) return init_mi_tree( 404, "Table not found", 15); /* process the aor */ aor = &node->next->value; if ( mi_fix_aor(aor)!=0 ) return init_mi_tree( 400, "Domain missing in AOR", 21); lock_udomain( dom, aor); ret = get_urecord( dom, aor, &rec); if (ret == 1) { unlock_udomain( dom, aor); return init_mi_tree( 404, "AOR not found", 13); } get_act_time(); rpl_tree = 0; rpl = 0; for( con=rec->contacts ; con ; con=con->next) { if (VALID_CONTACT( con, act_time)) { if (rpl_tree==0) { rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==0) goto error; rpl = &rpl_tree->node; } node = addf_mi_node_child( rpl, 0, "Contact", 7, "<%.*s>;q=%s;expires=%d;flags=0x%X;cflags=0x%X;socket=<%.*s>;" "methods=0x%X" "%s%.*s%s" /*received*/ "%s%.*s%s" /*user-agent*/ "%s%.*s%s" /*path*/ "%s%.*s" /*instance*/ ";reg-id=%u", con->c.len, ZSW(con->c.s), q2str(con->q, 0), (int)(con->expires - act_time), con->flags, con->cflags, con->sock?con->sock->sock_str.len:3, con->sock?con->sock->sock_str.s:"NULL", con->methods, con->received.len?";received=<":"",con->received.len, ZSW(con->received.s), con->received.len?">":"", con->user_agent.len?";user_agent=<":"",con->user_agent.len, ZSW(con->user_agent.s), con->user_agent.len?">":"", con->path.len?";path=<":"", con->path.len, ZSW(con->path.s), con->path.len?">":"", con->instance.len?";+sip.instance=":"", con->instance.len, ZSW(con->instance.s), con->reg_id ); if (node==0) goto error; } } unlock_udomain( dom, aor); if (rpl_tree==0) return init_mi_tree( 404 , "AOR has no contacts", 18); return rpl_tree; error: if (rpl_tree) free_mi_tree( rpl_tree ); unlock_udomain( dom, aor); return 0; }
/*! * \brief Add a node for a address of record * \param parent parent node * \param r printed record * \param t actual time * \param short_dump 0 means that all informations will be included, 1 that only the AOR is printed * \return 0 on success, -1 on failure */ static inline int mi_add_aor_node(struct mi_node *parent, urecord_t* r, time_t t, int short_dump) { struct mi_node *anode, *cnode, *node; struct mi_attr *attr; ucontact_t* c; char *p; int len; anode = add_mi_node_child( parent, MI_DUP_VALUE, "AOR", 3, r->aor.s, r->aor.len); if (anode==0) return -1; if (short_dump) return 0; #if 0 /* aor hash */ p = int2str((unsigned long)r->aorhash, &len); node = add_mi_node_child( anode, MI_DUP_VALUE, "HashID", 6, p, len); if (node==0) return -1; #endif for( c=r->contacts ; c ; c=c->next) { /* contact */ cnode = add_mi_node_child( anode, MI_DUP_VALUE, "Contact", 7, c->c.s, c->c.len); if (cnode==0) return -1; /* expires */ if (c->expires == 0) { node = add_mi_node_child( cnode, 0, "Expires", 7, "permanent", 9); } else if (c->expires == UL_EXPIRED_TIME) { node = add_mi_node_child( cnode, 0, "Expires", 7, "deleted", 7); } else if (t > c->expires) { node = add_mi_node_child( cnode, 0, "Expires", 7, "expired", 7); } else { p = int2str((unsigned long)(c->expires - t), &len); node = add_mi_node_child( cnode, MI_DUP_VALUE, "Expires", 7,p,len); } if (node==0) return -1; /* q */ p = q2str(c->q, (unsigned int*)&len); attr = add_mi_attr( cnode, MI_DUP_VALUE, "Q", 1, p, len); if (attr==0) return -1; /* callid */ node = add_mi_node_child( cnode, MI_DUP_VALUE, "Callid", 6, c->callid.s, c->callid.len); if (node==0) return -1; /* cseq */ p = int2str((unsigned long)c->cseq, &len); node = add_mi_node_child( cnode, MI_DUP_VALUE, "Cseq", 4, p, len); if (node==0) return -1; /* User-Agent */ if (c->user_agent.len) { node = add_mi_node_child( cnode, MI_DUP_VALUE, "User-agent", 10, c->user_agent.s, c->user_agent.len); if (node==0) return -1; } /* received */ if (c->received.len) { node = add_mi_node_child( cnode, MI_DUP_VALUE, "Received", 8, c->received.s, c->received.len); if (node==0) return -1; } /* path */ if (c->path.len) { node = add_mi_node_child( cnode, MI_DUP_VALUE, "Path", 4, c->path.s, c->path.len); if (node==0) return -1; } /* state */ if (c->state == CS_NEW) { node = add_mi_node_child( cnode, 0, "State", 5, "CS_NEW", 6); } else if (c->state == CS_SYNC) { node = add_mi_node_child( cnode, 0, "State", 5, "CS_SYNC", 7); } else if (c->state== CS_DIRTY) { node = add_mi_node_child( cnode, 0, "State", 5, "CS_DIRTY", 8); } else { node = add_mi_node_child( cnode, 0, "State", 5, "CS_UNKNOWN", 10); } if (node==0) return -1; /* flags */ p = int2str((unsigned long)c->flags, &len); node = add_mi_node_child( cnode, MI_DUP_VALUE, "Flags", 5, p, len); if (node==0) return -1; /* cflags */ p = int2str((unsigned long)c->cflags, &len); node = add_mi_node_child( cnode, MI_DUP_VALUE, "Cflags", 5, p, len); if (node==0) return -1; /* socket */ if (c->sock) { node = add_mi_node_child( cnode, 0, "Socket", 6, c->sock->sock_str.s, c->sock->sock_str.len); if (node==0) return -1; } /* methods */ p = int2str((unsigned long)c->methods, &len); node = add_mi_node_child( cnode, MI_DUP_VALUE, "Methods", 7, p, len); if (node==0) return -1; /* ruid */ if (c->ruid.len) { node = add_mi_node_child( cnode, MI_DUP_VALUE, "Ruid", 4, c->ruid.s, c->ruid.len); if (node==0) return -1; } /* instance */ if (c->instance.len) { node = add_mi_node_child( cnode, MI_DUP_VALUE, "Instance", 8, c->instance.s, c->instance.len); if (node==0) return -1; } /* reg-id */ p = int2str((unsigned long)c->reg_id, &len); node = add_mi_node_child( cnode, MI_DUP_VALUE, "Reg-Id", 6, p, len); if (node==0) return -1; /* last keepalive */ p = int2str((unsigned long)c->last_keepalive, &len); node = add_mi_node_child( cnode, MI_DUP_VALUE, "Last-Keepalive", 14, p, len); if (node==0) return -1; /* last modified */ p = int2str((unsigned long)c->last_modified, &len); node = add_mi_node_child( cnode, MI_DUP_VALUE, "Last-Modified", 13, p, len); if (node==0) return -1; } /* for */ return 0; }
int build_contact(ucontact_t* c, contact_for_header_t** contact_header) { char *p, *cp; int fl, len; *contact_header = 0; contact_for_header_t* tmp_contact_header = shm_malloc(sizeof (contact_for_header_t)); if (!tmp_contact_header) { LM_ERR("no more memory\n"); return -1; } memset(tmp_contact_header, 0, sizeof (contact_for_header_t)); tmp_contact_header->data_len = calc_buf_len(c); tmp_contact_header->buf = (char*)shm_malloc(tmp_contact_header->data_len); p = tmp_contact_header->buf; memcpy(p, CONTACT_BEGIN, CONTACT_BEGIN_LEN); p += CONTACT_BEGIN_LEN; fl = 0; while (c) { if (VALID_CONTACT(c, act_time)) { if (fl) { memcpy(p, CONTACT_SEP, CONTACT_SEP_LEN); p += CONTACT_SEP_LEN; } else { fl = 1; } *p++ = '<'; memcpy(p, c->c.s, c->c.len); p += c->c.len; *p++ = '>'; len = len_q(c->q); if (len) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; memcpy(p, q2str(c->q, 0), len); p += len; } memcpy(p, EXPIRES_PARAM, EXPIRES_PARAM_LEN); p += EXPIRES_PARAM_LEN; cp = int2str((int) (c->expires - act_time), &len); memcpy(p, cp, len); p += len; if (c->received.s) { *p++ = ';'; memcpy(p, rcv_param.s, rcv_param.len); p += rcv_param.len; *p++ = '='; *p++ = '\"'; memcpy(p, c->received.s, c->received.len); p += c->received.len; *p++ = '\"'; } } c = c->next; } memcpy(p, CRLF, CRLF_LEN); p += CRLF_LEN; tmp_contact_header->data_len = p - tmp_contact_header->buf; LM_DBG("created Contact HF: %.*s\n", tmp_contact_header->data_len, tmp_contact_header->buf); *contact_header = tmp_contact_header; return 0; }
static int xl_get_branches(struct sip_msg *msg, str *res, str *hp, int hi, int hf) { str uri; qvalue_t q; int len, cnt, i; unsigned int qlen; char *p, *qbuf; if(msg==NULL || res==NULL) return -1; if(msg->first_line.type == SIP_REPLY) return xl_get_null(msg, res, hp, hi, hf); cnt = len = 0; init_branch_iterator(); while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0))) { cnt++; len += uri.len; if (q != Q_UNSPECIFIED) { len += 1 + Q_PARAM_LEN + len_q(q); } } if (cnt == 0) return xl_get_empty(msg, res, hp, hi, hf); len += (cnt - 1) * XLOG_FIELD_DELIM_LEN; if (len + 1 > LOCAL_BUF_SIZE) { LOG(L_ERR, "ERROR:xl_get_branches: local buffer length exceeded\n"); return xl_get_null(msg, res, hp, hi, hf); } i = 0; p = local_buf; init_branch_iterator(); while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0))) { if (i) { memcpy(p, XLOG_FIELD_DELIM, XLOG_FIELD_DELIM_LEN); p += XLOG_FIELD_DELIM_LEN; } if (q != Q_UNSPECIFIED) { *p++ = '<'; } memcpy(p, uri.s, uri.len); p += uri.len; if (q != Q_UNSPECIFIED) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; qbuf = q2str(q, &qlen); memcpy(p, qbuf, qlen); p += qlen; } i++; } res->s = &(local_buf[0]); res->len = len; return 0; }
/*! \brief * Allocate a memory buffer and print Contact * header fields into it */ int build_contact(ucontact_t* c,struct sip_msg *_m) { char *p, *cp, *tmpgr; int fl, len,grlen; int build_gruu = 0; struct socket_info *sock; if (!disable_gruu && _m->supported && parse_supported(_m) == 0 && (get_supported(_m) & F_SUPPORTED_GRUU)) build_gruu=1; contact.data_len = calc_buf_len(c,build_gruu,_m); if (!contact.data_len) return 0; if (!contact.buf || (contact.buf_len < contact.data_len)) { if (contact.buf) pkg_free(contact.buf); contact.buf = (char*)pkg_malloc(contact.data_len); if (!contact.buf) { contact.data_len = 0; contact.buf_len = 0; LM_ERR("no pkg memory left\n"); return -1; } else { contact.buf_len = contact.data_len; } } p = contact.buf; memcpy(p, CONTACT_BEGIN, CONTACT_BEGIN_LEN); p += CONTACT_BEGIN_LEN; fl = 0; while(c) { if (VALID_CONTACT(c, get_act_time())) { if (fl) { memcpy(p, CONTACT_SEP, CONTACT_SEP_LEN); p += CONTACT_SEP_LEN; } else { fl = 1; } *p++ = '<'; memcpy(p, c->c.s, c->c.len); p += c->c.len; *p++ = '>'; len = len_q(c->q); if (len) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; memcpy(p, q2str(c->q, 0), len); p += len; } memcpy(p, EXPIRES_PARAM, EXPIRES_PARAM_LEN); p += EXPIRES_PARAM_LEN; cp = int2str((int)(c->expires - get_act_time()), &len); memcpy(p, cp, len); p += len; if (c->received.s) { *p++ = ';'; memcpy(p, rcv_param.s, rcv_param.len); p += rcv_param.len; *p++ = '='; *p++ = '\"'; memcpy(p, c->received.s, c->received.len); p += c->received.len; *p++ = '\"'; } if (build_gruu && c->instance.s) { sock = (c->sock)?(c->sock):(_m->rcv.bind_address); /* build pub GRUU */ memcpy(p,PUB_GRUU,PUB_GRUU_SIZE); p += PUB_GRUU_SIZE; *p++ = '\"'; memcpy(p,SIP_PROTO,SIP_PROTO_SIZE); p += SIP_PROTO_SIZE; memcpy(p,c->aor->s,c->aor->len); p += c->aor->len; if (!reg_use_domain) { *p++ = '@'; memcpy(p,sock->name.s,sock->name.len); p += sock->name.len; *p++ = ':'; memcpy(p,sock->port_no_str.s,sock->port_no_str.len); p += sock->port_no_str.len; } memcpy(p,GR_PARAM,GR_PARAM_SIZE); p += GR_PARAM_SIZE; memcpy(p,c->instance.s+1,c->instance.len-2); p += c->instance.len-2; *p++ = '\"'; /* build temp GRUU */ memcpy(p,TEMP_GRUU,TEMP_GRUU_SIZE); p += TEMP_GRUU_SIZE; *p++ = '\"'; memcpy(p,SIP_PROTO,SIP_PROTO_SIZE); p += SIP_PROTO_SIZE; memcpy(p,TEMP_GRUU_HEADER,TEMP_GRUU_HEADER_SIZE); p += TEMP_GRUU_HEADER_SIZE; tmpgr = build_temp_gruu(c->aor,&c->instance,&c->callid,&grlen); base64encode((unsigned char *)p, (unsigned char *)tmpgr,grlen); p += calc_temp_gruu_len(c->aor,&c->instance,&c->callid); *p++ = '@'; memcpy(p,sock->name.s,sock->name.len); p += sock->name.len; *p++ = ':'; memcpy(p,sock->port_no_str.s,sock->port_no_str.len); p += sock->port_no_str.len; memcpy(p,GR_NO_VAL,GR_NO_VAL_SIZE); p += GR_NO_VAL_SIZE; *p++ = '\"'; /* build +sip.instance */ memcpy(p,SIP_INSTANCE,SIP_INSTANCE_SIZE); p += SIP_INSTANCE_SIZE; *p++ = '\"'; memcpy(p,c->instance.s+1,c->instance.len-2); p += c->instance.len-2; *p++ = '\"'; } } c = c->next; } memcpy(p, CRLF, CRLF_LEN); p += CRLF_LEN; contact.data_len = p - contact.buf; LM_DBG("created Contact HF: %.*s\n", contact.data_len, contact.buf); return 0; }