Exemple #1
0
/*! \brief
 * Calculate the length of buffer needed to
 * print contacts
 */
static inline unsigned int calc_buf_len(impurecord_t* impurec) {
    unsigned int len;
    int qlen;
    int i=0;
    ucontact_t* c;

    len = 0;
    while (i<MAX_CONTACTS_PER_IMPU && (c=impurec->newcontacts[i])) {
        if (VALID_CONTACT(c, act_time)) {
            if (len) len += CONTACT_SEP_LEN;
            len += 2 /* < > */ + c->c.len;
            qlen = len_q(c->q);
            if (qlen) len += Q_PARAM_LEN + qlen;
            len += EXPIRES_PARAM_LEN + INT2STR_MAX_LEN;
            if (c->received.s) {
                len += 1 /* ; */
                        + rcv_param.len
                        + 1 /* = */
                        + 1 /* dquote */
                        + c->received.len
                        + 1 /* dquote */
                        ;
            }
        }
	i++;
    }

    if (len) len += CONTACT_BEGIN_LEN + CRLF_LEN;
    return len;
}
Exemple #2
0
/*! \brief
 * Calculate the length of buffer needed to
 * print contacts
 */
static inline unsigned int calc_buf_len(ucontact_t* c)
{
	unsigned int len;
	int qlen;

	len = 0;
	while(c) {
		if (VALID_CONTACT(c, act_time)) {
			if (len) len += CONTACT_SEP_LEN;
			len += 2 /* < > */ + c->c.len;
			qlen = len_q(c->q);
			if (qlen) len += Q_PARAM_LEN + qlen;
			len += EXPIRES_PARAM_LEN + INT2STR_MAX_LEN;
			if (c->received.s) {
				len += 1 /* ; */ 
					+ rcv_param.len 
					+ 1 /* = */ 
					+ 1 /* dquote */ 
					+ c->received.len
					+ 1 /* dquote */
					;
			}
		}
		c = c->next;
	}

	if (len) len += CONTACT_BEGIN_LEN + CRLF_LEN;
	return len;
}
Exemple #3
0
/* Execute random quench algorithm on an interface's output queue */
void
rquench(
struct iface *ifp,
int drop
){
	struct mbuf *bp,*bplast;
	int i;
	struct qhdr qhdr;
	struct ip ip;
	struct mbuf *bpdup;

	if((i = len_q(ifp->outq)) == 0)
		return;	/* Queue is empty */

	i = urandom(i);	/* Select a victim */

	/* Search for i-th message on queue */
	bplast = NULL;
	for(bp = ifp->outq;bp != NULL && i>0;i--,bplast=bp,bp=bp->anext)
		;
	if(bp == NULL)
		return;	/* "Can't happen" */

	/* Send a source quench */
	dup_p(&bpdup,bp,0,len_p(bp));
	pullup(&bpdup,&qhdr,sizeof(qhdr));
	ntohip(&ip,&bpdup);
	icmp_output(&ip,bpdup,ICMP_QUENCH,0,NULL);
	free_p(&bpdup);
	if(!drop)
		return;	/* All done */

	/* Drop the packet */
	if(bplast != NULL)
		bplast->anext = bp->anext;
	else
		ifp->outq = bp->anext;	/* First on list */
	free_p(&bp);
}
Exemple #4
0
/* Dump ARP table */
static void
dumparp(void)
{
	int i;
	struct arp_tab *ap;
	char e[128];

	arp_loadfile();
	printf("received %u badtype %u bogus addr %u reqst in %u replies %u reqst out %u\n",
	 Arp_stat.recv,Arp_stat.badtype,Arp_stat.badaddr,Arp_stat.inreq,
	 Arp_stat.replies,Arp_stat.outreq);

	printf("IP addr            Type              Time Q Addr\n");
	for(i=0;i<HASHMOD;i++){
		for(ap = Arp_tab[i];ap != (struct arp_tab *)NULL;ap = ap->next){
			printf("%-18.18s ",inet_ntoa(ap->ip_addr));
			printf("%-15s",smsg(Arptypes,NHWTYPES,ap->hardware));
			printf("%7ld ",read_timer(&ap->timer)/1000L);
			if(ap->state == ARP_PENDING)
				printf("%-2u",len_q(ap->pending));
			else
				printf("  ");
			if(ap->state == ARP_VALID){
				if(Arp_type[ap->hardware].format != NULL){
					(*Arp_type[ap->hardware].format)(e,ap->hw_addr);
				} else {
					e[0] = '\0';
				}
				printf("%s",e);
			} else {
				printf("[unknown]");
			}
			if(ap->pub)
				printf(" (published)");
			printf("\n");
		}
	}
}
Exemple #5
0
/*! \brief
 * Calculate the length of buffer needed to
 * print contacts
 * - mode specifies if GRUU header params are added
 */
static inline unsigned int calc_buf_len(ucontact_t* c, str *host, int mode)
{
	unsigned int len;
	int qlen;

	len = 0;
	while(c) {
		if (VALID_CONTACT(c, act_time)) {
			if (len) len += CONTACT_SEP_LEN;
			len += 2 /* < > */ + c->c.len;
			qlen = len_q(c->q);
			if (qlen) len += Q_PARAM_LEN + qlen;
			len += EXPIRES_PARAM_LEN + INT2STR_MAX_LEN;
			if (rcv_param.len>0 && c->received.s) {
				len += 1 /* ; */ 
					+ rcv_param.len 
					+ 1 /* = */ 
					+ 1 /* dquote */ 
					+ c->received.len
					+ 1 /* dquote */
					;
			}
			if (reg_gruu_enabled==1 && c->instance.len>0 && mode==1) {
				/* pub-gruu */
				len += PUB_GRUU_PARAM_LEN
					+ 1 /* " */
					+ 4 /* sip: */
					+ c->aor->len
					+ 1 /* @ */
					+ host->len
					+ GR_PARAM_LEN
					+ c->instance.len
					+ 1 /* " */
					;
				/* temp-gruu */
				len += TMP_GRUU_PARAM_LEN
					+ 1 /* " */
					+ 4 /* sip: */
					+ c->ruid.len
					+ 1 /* 'sep' */
					+ 8 /* max hex int */
					+ 1 /* @ */
					+ host->len
					+ GR_PARAM_LEN
					- 1 /* = */
					+ 1 /* " */
					;
			}
			if (c->instance.len>0) {
				/* +sip-instance */
				len += SIP_INSTANCE_PARAM_LEN
					+ 1 /* " */
					+ c->instance.len
					+ 1 /* " */
					;
			}
			if (c->reg_id>0) {
				/* reg-id */
				len += REG_ID_PARAM_LEN + INT2STR_MAX_LEN;
			}
		}
		c = c->next;
	}

	if (len) len += CONTACT_BEGIN_LEN + CRLF_LEN;
	return len;
}
Exemple #6
0
/*! \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(&reg_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;
	}
Exemple #7
0
/*
 * 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;
}
Exemple #8
0
/*! \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;
}
Exemple #9
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;
}
Exemple #10
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;
}
Exemple #11
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;
}
Exemple #12
0
/*! \brief
 * Calculate the length of buffer needed to
 * print contacts
 */
static inline unsigned int calc_buf_len(ucontact_t* c,int build_gruu,
		struct sip_msg *_m)
{
	unsigned int len;
	int qlen;
	struct socket_info *sock;

	len = 0;
	while(c) {
		if (VALID_CONTACT(c, get_act_time())) {
			if (len) len += CONTACT_SEP_LEN;
			len += 2 /* < > */ + c->c.len;
			qlen = len_q(c->q);
			if (qlen) len += Q_PARAM_LEN + qlen;
			len += EXPIRES_PARAM_LEN + INT2STR_MAX_LEN;
			if (c->received.s) {
				len += 1 /* ; */
					+ rcv_param.len
					+ 1 /* = */
					+ 1 /* dquote */
					+ c->received.len
					+ 1 /* dquote */
					;
			}
			if (build_gruu && c->instance.s) {
				sock = (c->sock)?(c->sock):(_m->rcv.bind_address);
				/* pub gruu */
				len += PUB_GRUU_SIZE
					+ 1 /* quote */
					+ SIP_PROTO_SIZE
					+ c->aor->len
					+ (reg_use_domain ?0:(1 /* @ */ + sock->name.len + 1 /* : */ + sock->port_no_str.len))
					+ GR_PARAM_SIZE
					+ (c->instance.len - 2)
					+ 1 /* quote */
					;
				/* temp gruu */
				len += TEMP_GRUU_SIZE
					+ 1 /* quote */
					+ SIP_PROTO_SIZE
					+ TEMP_GRUU_HEADER_SIZE
					+ calc_temp_gruu_len(c->aor,&c->instance,&c->callid)
					+ 1 /* @ */
					+ sock->name.len
					+ 1 /* : */
					+ sock->port_no_str.len
					+ GR_NO_VAL_SIZE
					+ 1 /* quote */
					;
				/* sip.instance */
				len += SIP_INSTANCE_SIZE
					+ 1 /* quote */
					+ (c->instance.len - 2)
					+ 1 /* quote */
					;
			}
		}
		c = c->next;
	}

	if (len) len += CONTACT_BEGIN_LEN + CRLF_LEN;
	return len;
}