[Serusers] Extending usrloc module to allow to save User-Agent values [patch for review]

Maxim Sobolev sobomax at portaone.com
Mon Apr 28 23:33:57 CEST 2003


Folks,

Attached please find a patch, which extends usrloc/registrar modules
to save values from User-Agent field in REGISTER messages into the
database. It would be nice to have it included into the next release.
Please disregard hackish detection of User-Agent fields, I am currently
working on extending parser to recognize that type of field. I'll
post updated patch when finished.

Also, there is a new unrelated function which can be used to
retrieve full list of all currently registered users in all domains.
I am using this function in new version of my nathelper modules to
do periodical UDP "pinging" of all registered users to keep their NAT
bindings alive. I would like to have it reviewed and included into
the next release as well.

Thanks!

-Maxim

-------------- next part --------------
--- modules/usrloc/dlist.c	2003/04/17 00:07:56	1.1
+++ modules/usrloc/dlist.c	2003/04/18 10:50:09
@@ -29,6 +29,7 @@
 
 
 #include "dlist.h"
+#include <stdlib.h>	       /* abort */
 #include <string.h>            /* strlen, memcmp */
 #include <stdio.h>             /* printf */
 #include "../../mem/shm_mem.h"
@@ -67,6 +68,73 @@
 	return 1;
 }
 
+/*
+ * Return list of all contacts for all currently registered
+ * users in all domains. Caller must provide buffer of
+ * sufficient length for fitting all those contacts. In the
+ * case when buffer was exhausted, the function returns
+ * estimated amount of additional space needed, in this
+ * case the caller is expected to repeat the call using
+ * this value as the hint.
+ *
+ * Information is packed into the buffer as follows:
+ *
+ * +------------+----------+------------+-----------
+ * |contact1.len|contact1.s|contact2.len|contact2.s|
+ * +------------+----------+------------+-----------
+ * |.......................|contactN.len|contactN.s|
+ * +------------+----------+------------+----------+
+ * |000000000000|
+ * +------------+
+ */
+int get_all_ucontacts(void *buf, int len)
+{
+	dlist_t *p;
+	urecord_t *r;
+	ucontact_t *c;
+	void *cp;
+	int shortage;
+
+	cp = buf;
+	shortage = 0;
+	/* Reserve space for terminating 0000 */
+	len -= sizeof(c->c.len);
+	for (p = root; p != NULL; p = p->next) {
+		lock_udomain(p->d);
+		if (p->d->d_ll.n <= 0) {
+			unlock_udomain(p->d);
+			continue;
+		}
+		for (r = p->d->d_ll.first; r != NULL; r = r->d_ll.next) {
+			for (c = r->contacts; c != NULL; c = c->next) {
+				if (c->c.len <= 0)
+					continue;
+				if (len >= (int)(sizeof(c->c.len) + c->c.len)) {
+					memcpy(cp, &c->c.len, sizeof(c->c.len));
+					cp += sizeof(c->c.len);
+					memcpy(cp, c->c.s, c->c.len);
+					cp += c->c.len;
+					len -= sizeof(c->c.len) + c->c.len;
+				} else {
+					shortage += sizeof(c->c.len) + c->c.len;
+				}
+			}
+		}
+		unlock_udomain(p->d);
+	}
+	/* len < 0 is possible, if size of the buffer < sizeof(c->c.len) */
+	if (len >= 0)
+		bzero(cp, sizeof(c->c.len));
+
+	/* Shouldn't happen */
+	if (shortage > 0 && len > shortage) {
+		abort();
+	}
+
+	shortage -= len;
+
+	return shortage > 0 ? shortage : 0;
+}
 
 /*
  * Create a new domain structure
--- modules/usrloc/dlist.h	2003/04/17 22:30:32	1.1
+++ modules/usrloc/dlist.h	2003/04/17 22:31:40
@@ -80,5 +80,9 @@
  */
 int preload_all_udomains(void);
 
+/*
+ * Get contacts to all registered users
+ */
+int get_all_ucontacts(void *, int);
 
 #endif /* UDLIST_H */
--- modules/usrloc/ins_list.c	2003/04/29 18:39:43	1.1
+++ modules/usrloc/ins_list.c	2003/04/29 18:44:07
@@ -56,6 +56,7 @@
 	p->user = _c->aor;
 	p->cont = &_c->c;
 	p->cid_len = _c->callid.len;
+	p->user_agent = &_c->user_agent;
 
 	memcpy(p->callid, _c->callid.s, p->cid_len);
 
@@ -69,8 +70,8 @@
 {
 	struct ins_itm* p;
 	char b[256];
-	db_key_t keys[] = {user_col, contact_col, expires_col, q_col, callid_col, cseq_col};
-	db_val_t vals[6];
+	db_key_t keys[] = {user_col, contact_col, expires_col, q_col, callid_col, cseq_col, user_agent_col};
+	db_val_t vals[7];
 	
 	if (ins_root) {
 	     /* FIXME */
@@ -84,6 +85,7 @@
 		VAL_TYPE(vals + 3) = DB_DOUBLE;
 		VAL_TYPE(vals + 4) = DB_STR;
 		VAL_TYPE(vals + 5) = DB_INT;
+		VAL_TYPE(vals + 6) = DB_STR;
 
 		VAL_NULL(vals) = 0;
 		VAL_NULL(vals + 1) = 0;
@@ -91,6 +93,7 @@
 		VAL_NULL(vals + 3) = 0;
 		VAL_NULL(vals + 4) = 0;
 		VAL_NULL(vals + 5) = 0;
+		VAL_NULL(vals + 6) = 0;
 	}
 
 	while(ins_root) {
@@ -111,7 +114,10 @@
 
 		VAL_INT(vals + 5) = p->cseq;
 
-		if (db_insert(db, keys, vals, 6) < 0) {
+		VAL_STR(vals + 6).len = p->user_agent->len;
+		VAL_STR(vals + 6).s = p->user_agent->s;
+
+		if (db_insert(db, keys, vals, 7) < 0) {
 			LOG(L_ERR, "process_ins_list(): Error while deleting from database\n");
 			return -1;
 		}
--- modules/usrloc/ins_list.h	2003/04/29 18:43:34	1.1
+++ modules/usrloc/ins_list.h	2003/04/29 18:44:21
@@ -42,6 +42,7 @@
 	int cseq;
 	str* user;
 	str* cont;
+	str* user_agent;
 	int cid_len;
 	char callid[0];
 };
--- modules/usrloc/ucontact.c	2003/04/29 18:31:15	1.1
+++ modules/usrloc/ucontact.c	2003/04/29 19:05:50
@@ -41,7 +41,7 @@
  * Create a new contact structure
  */
 int new_ucontact(str* _dom, str* _aor, str* _contact, time_t _e, float _q,
-		 str* _callid, int _cseq, ucontact_t** _c)
+		 str* _callid, int _cseq, str* _ua, ucontact_t** _c)
 {
 	*_c = (ucontact_t*)shm_malloc(sizeof(ucontact_t));
 	if (!(*_c)) {
@@ -75,6 +75,17 @@
 	memcpy((*_c)->callid.s, _callid->s, _callid->len);
 	(*_c)->callid.len = _callid->len;
 
+	(*_c)->user_agent.s = (char*)shm_malloc(_ua->len);
+	if ((*_c)->user_agent.s == 0) {
+		LOG(L_ERR, "new_ucontact(): No memory left 8\n");
+		shm_free((*_c)->callid.s);
+		shm_free((*_c)->c.s);
+		shm_free(*_c);
+		return -8;
+	}
+	memcpy((*_c)->user_agent.s, _ua->s, _ua->len);
+	(*_c)->user_agent.len = _ua->len;
+
 	(*_c)->cseq = _cseq;
 	(*_c)->next = 0;
 	(*_c)->prev = 0;
@@ -89,6 +100,7 @@
  */
 void free_ucontact(ucontact_t* _c)
 {
+		shm_free(_c->user_agent.s);
 		shm_free(_c->callid.s);
 		shm_free(_c->c.s);
 		shm_free(_c);
@@ -111,16 +123,17 @@
 	}
 
 	fprintf(_f, "~~~Contact(%p)~~~\n", _c);
-	fprintf(_f, "domain : \'%.*s\'\n", _c->domain->len, _c->domain->s);
-	fprintf(_f, "aor    : \'%.*s\'\n", _c->aor->len, _c->aor->s);
-	fprintf(_f, "Contact: \'%.*s\'\n", _c->c.len, _c->c.s);
-	fprintf(_f, "Expires: %u\n", (unsigned int)(_c->expires - t));
-	fprintf(_f, "q      : %10.2f\n", _c->q);
-	fprintf(_f, "Call-ID: \'%.*s\'\n", _c->callid.len, _c->callid.s);
-	fprintf(_f, "CSeq   : %d\n", _c->cseq);
-	fprintf(_f, "State  : %s\n", st);
-	fprintf(_f, "next   : %p\n", _c->next);
-	fprintf(_f, "prev   : %p\n", _c->prev);
+	fprintf(_f, "domain    : \'%.*s\'\n", _c->domain->len, _c->domain->s);
+	fprintf(_f, "aor       : \'%.*s\'\n", _c->aor->len, _c->aor->s);
+	fprintf(_f, "Contact   : \'%.*s\'\n", _c->c.len, _c->c.s);
+	fprintf(_f, "Expires   : %u\n", (unsigned int)(_c->expires - t));
+	fprintf(_f, "q         : %10.2f\n", _c->q);
+	fprintf(_f, "Call-ID   : \'%.*s\'\n", _c->callid.len, _c->callid.s);
+	fprintf(_f, "CSeq      : %d\n", _c->cseq);
+	fprintf(_f, "User-Agent: \'%.*s\'\n", _c->user_agent.len, _c->user_agent.s);
+	fprintf(_f, "State     : %s\n", st);
+	fprintf(_f, "next      : %p\n", _c->next);
+	fprintf(_f, "prev      : %p\n", _c->prev);
 	fprintf(_f, "~~~/Contact~~~~\n");
 }
 
@@ -128,7 +141,7 @@
 /*
  * Update ucontact structure in memory
  */
-int mem_update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs)
+int mem_update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs, str* _ua)
 {
 	char* ptr;
 	
@@ -146,7 +159,22 @@
 		memcpy(_c->callid.s, _cid->s, _cid->len);
 	}
 	_c->callid.len = _cid->len;
-	
+
+	if (_c->user_agent.len < _ua->len) {
+		ptr = (char*)shm_malloc(_ua->len);
+		if (ptr == 0) {
+			LOG(L_ERR, "update_ucontact(): No memory left\n");
+			return -1;
+		}
+
+		memcpy(ptr, _ua->s, _ua->len);
+		shm_free(_c->user_agent.s);
+		_c->user_agent.s = ptr;
+	} else {
+		memcpy(_c->user_agent.s, _ua->s, _ua->len);
+	}
+	_c->user_agent.len = _ua->len;
+
 	_c->expires = _e;
 	_c->q = _q;
 	_c->cseq = _cs;
@@ -297,14 +325,15 @@
 {
 	char b[256];
 	db_key_t keys[] = {user_col, contact_col, expires_col, q_col, callid_col,
-						cseq_col};
+						cseq_col, user_agent_col};
 	db_val_t vals[] = {
 			  {DB_STR,      0, {.str_val = {_c->aor->s, _c->aor->len}}},
 			  {DB_STR,      0, {.str_val = {_c->c.s, _c->c.len}}},
 			  {DB_DATETIME, 0, {.time_val = _c->expires}},
 			  {DB_DOUBLE,   0, {.double_val = _c->q}},
 			  {DB_STR,      0, {.str_val = {_c->callid.s, _c->callid.len}}},
-			  {DB_INT,      0, {.int_val = _c->cseq}}
+			  {DB_INT,      0, {.int_val = _c->cseq}},
+			  {DB_STR,      0, {.str_val = {_c->user_agent.s, _c->user_agent.len}}}
 	};
 
 	     /* FIXME */
@@ -312,7 +341,7 @@
 	b[_c->domain->len] = '\0';
 	db_use_table(db, b);
 
-	if (db_insert(db, keys, vals, 6) < 0) {
+	if (db_insert(db, keys, vals, 7) < 0) {
 		LOG(L_ERR, "db_ins_ucontact(): Error while inserting contact\n");
 		return -1;
 	}
@@ -332,11 +361,12 @@
 			     {DB_STR, 0, {.str_val = {_c->c.s, _c->c.len}}}
 	};
 
-	db_key_t keys2[4] = {expires_col, q_col, callid_col, cseq_col};
-	db_val_t vals2[4] = {{DB_DATETIME, 0, {.time_val = _c->expires}},
+	db_key_t keys2[5] = {expires_col, q_col, callid_col, cseq_col, user_agent_col};
+	db_val_t vals2[5] = {{DB_DATETIME, 0, {.time_val = _c->expires}},
 			     {DB_DOUBLE,   0, {.double_val = _c->q}},
 			     {DB_STR,      0, {.str_val = {_c->callid.s, _c->callid.len}}},
-			     {DB_INT,      0, {.int_val = _c->cseq}}
+			     {DB_INT,      0, {.int_val = _c->cseq}},
+			     {DB_STR,      0, {.str_val = {_c->user_agent.s, _c->user_agent.len}}}
 	};
 
 	     /* FIXME */
@@ -344,7 +374,7 @@
 	b[_c->domain->len] = '\0';
 	db_use_table(db, b);
 
-	if (db_update(db, keys1, vals1, keys2, vals2, 2, 4) < 0) {
+	if (db_update(db, keys1, vals1, keys2, vals2, 2, 5) < 0) {
 		LOG(L_ERR, "db_upd_ucontact(): Error while updating database\n");
 		return -1;
 	}
@@ -381,14 +411,14 @@
 /*
  * Update ucontact with new values
  */
-int update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs)
+int update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs, str* _ua)
 {
 	switch(db_mode) {
 	case NO_DB:
-		return mem_update_ucontact(_c, _e, _q, _cid, _cs);
+		return mem_update_ucontact(_c, _e, _q, _cid, _cs, _ua);
 		
 	case WRITE_THROUGH:
-		if (mem_update_ucontact(_c, _e, _q, _cid, _cs) < 0) {
+		if (mem_update_ucontact(_c, _e, _q, _cid, _cs, _ua) < 0) {
 			LOG(L_ERR, "update_ucontact(): Error while updating\n");
 			return -1;
 		}
@@ -400,7 +430,7 @@
 
 	case WRITE_BACK:
 		st_update_ucontact(_c);
-		return mem_update_ucontact(_c, _e, _q, _cid, _cs);
+		return mem_update_ucontact(_c, _e, _q, _cid, _cs, _ua);
 	}
 	return 0;
 }
--- modules/usrloc/ucontact.h	2003/04/29 18:25:43	1.1
+++ modules/usrloc/ucontact.h	2003/04/29 19:07:46
@@ -53,6 +53,7 @@
 	str callid;            /* Call-ID header field */
         int cseq;              /* CSeq value */
 	cstate_t state;        /* State of the contact */
+	str user_agent;        /* User-Agent */
 	struct ucontact* next; /* Next contact in the linked list */
 	struct ucontact* prev; /* Previous contact in the linked list */
 } ucontact_t;
@@ -62,7 +63,7 @@
  * Create a new contact structure
  */
 int new_ucontact(str* _dom, str* _aor, str* _contact, time_t _e, float _q, 
-		 str* _callid, int _cseq, ucontact_t** _c);
+		 str* _callid, int _cseq, str* _ua, ucontact_t** _c);
 
 
 /*
@@ -80,7 +81,7 @@
 /*
  * Update existing contact in memory with new values
  */
-int mem_update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs);
+int mem_update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs, str* _ua);
 
 
 
@@ -148,7 +149,7 @@
 /*
  * Update ucontact with new values
  */
-int update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs);
+int update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs, str* _ua);
 
 
 #endif /* UCONTACT_H */
--- modules/usrloc/udomain.c	2003/04/17 11:44:57	1.1
+++ modules/usrloc/udomain.c	2003/04/29 19:04:30
@@ -198,12 +198,12 @@
 int preload_udomain(udomain_t* _d)
 {
 	char b[256];
-	db_key_t columns[6] = {user_col, contact_col, expires_col, q_col, callid_col, cseq_col};
+	db_key_t columns[7] = {user_col, contact_col, expires_col, q_col, callid_col, cseq_col, user_agent_col};
 	db_res_t* res;
 	db_row_t* row;
 	int i, cseq;
 	
-	str user, contact, callid;
+	str user, contact, callid, ua;
 	time_t expires;
 	float q;
 
@@ -213,7 +213,7 @@
 	memcpy(b, _d->name->s, _d->name->len);
 	b[_d->name->len] = '\0';
 	db_use_table(db, b);
-	if (db_query(db, 0, 0, columns, 0, 6, 0, &res) < 0) {
+	if (db_query(db, 0, 0, columns, 0, 7, 0, &res) < 0) {
 		LOG(L_ERR, "preload_udomain(): Error while doing db_query\n");
 		return -1;
 	}
@@ -238,6 +238,8 @@
 		cseq        = VAL_INT   (ROW_VALUES(row) + 5);
 		callid.s    = (char*)VAL_STRING(ROW_VALUES(row) + 4);
 		callid.len  = strlen(callid.s);
+		ua.s        = (char*)VAL_STRING(ROW_VALUES(row) + 6);
+		ua.len      = strlen(ua.s);
 
 		if (get_urecord(_d, &user, &r) > 0) {
 			if (mem_insert_urecord(_d, &user, &r) < 0) {
@@ -248,7 +250,7 @@
 			}
 		}
 		
-		if (mem_insert_ucontact(r, &contact, expires, q, &callid, cseq, &c) < 0) {
+		if (mem_insert_ucontact(r, &contact, expires, q, &callid, cseq, &ua, &c) < 0) {
 			LOG(L_ERR, "preload_udomain(): Error while inserting contact\n");
 			db_free_query(db, res);
 			unlock_udomain(_d);
--- modules/usrloc/ul_fifo.c	2003/04/29 19:12:33	1.1
+++ modules/usrloc/ul_fifo.c	2003/04/29 19:16:23
@@ -48,8 +48,10 @@
  */
 #define FIFO_CALLID "The-Answer-To-The-Ultimate-Question-Of-Life-Universe-And-Everything"
 #define FIFO_CSEQ 42 
+#define FIFO_UA "SIP Express Router FIFO"
 
 #define FIFO_CALLID_LEN 67
+#define FIFO_UA_LEN 23
 
 
 /*
@@ -191,6 +193,7 @@
 	ucontact_t* c = 0;
 	int res;
 	str cid;
+	str ua;
 	
 	if (_e == 0) {
 		LOG(L_ERR, "fifo_add_contact(): expires == 0, giving up\n");
@@ -220,15 +223,18 @@
 	cid.s = FIFO_CALLID;
 	cid.len = FIFO_CALLID_LEN;
 
+	ua.s = FIFO_UA;
+	ua.len = FIFO_UA_LEN;
+
 	if (c) {
-		if (update_ucontact(c, _e + act_time, _q, &cid, FIFO_CSEQ) < 0) {
+		if (update_ucontact(c, _e + act_time, _q, &cid, FIFO_CSEQ, &ua) < 0) {
 			LOG(L_ERR, "fifo_add_contact(): Error while updating contact\n");
 			release_urecord(r);
 			return -5;
 		}
 	} else {
-		if (insert_ucontact(r, _c, _e + act_time, _q, &cid, FIFO_CSEQ, &c) < 0) {
-			LOG(L_ERR, "fifo_add_contact(): Error while inserting contact\n");
+		if (insert_ucontact(r, _c, _e + act_time, _q, &cid, FIFO_CSEQ, &ua, &c) < 0) {
+			LOG(L_ERR, "fifo_add_conact(): Error while inserting contact\n");
 			release_urecord(r);
 			return -6;
 		}
--- modules/usrloc/ul_mod.c	2003/04/17 22:26:34	1.1
+++ modules/usrloc/ul_mod.c	2003/04/29 18:39:16
@@ -56,6 +56,7 @@
 char* q_col          = "q";                                /* Name of column containing q values */
 char* callid_col     = "callid";                           /* Name of column containing callid string */
 char* cseq_col       = "cseq";                             /* Name of column containing cseq values */
+char* user_agent_col = "user_agent";                       /* Name of column containing name of user-agent */
 char* method_col     = "method";                           /* Name of column containing supported method */
 char* db_url         = "sql://ser:heslo@localhost/ser";    /* Database URL */
 int   timer_interval = 60;                                 /* Timer interval in seconds */
@@ -80,6 +81,7 @@
 		"~ul_insert_ucontact",  /* Insert a new contact into a record */
 		"~ul_delete_ucontact",  /* Remove a contact from a record */
 		"~ul_get_ucontact",     /* Return pointer to a contact */
+		"~ul_get_all_ucontacts",/* Retrieve contacts to all registered users */
 
 		"~ul_update_ucontact"   /* Update a contact */
 	},
@@ -96,16 +98,17 @@
 		(cmd_function)insert_ucontact,
 		(cmd_function)delete_ucontact,
 		(cmd_function)get_ucontact,
+		(cmd_function)get_all_ucontacts,
 
 		(cmd_function)update_ucontact
 	},
 	(int[]) {
-		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
 	},
 	(fixup_function[]) {
-		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 	},
-	11,
+	12,
 
 	(char*[]) {
 		"user_col",
@@ -114,6 +117,7 @@
 		"q_col",
 		"callid_col",
 		"cseq_col",
+		"user_agent_col",
 		"method_col",
 		"db_url",
 		"timer_interval",
@@ -129,6 +133,7 @@
 		STR_PARAM,
 		STR_PARAM,
 		STR_PARAM,
+		STR_PARAM,
 		INT_PARAM,
 		INT_PARAM
 	},
@@ -140,12 +145,13 @@
 		&q_col,
 		&callid_col,
 		&cseq_col,
+		&user_agent_col,
 		&method_col,
 		&db_url,
 		&timer_interval,
 		&db_mode
 	},
-	10,          /* Number of parameters */
+	11,          /* Number of parameters */
 
 	mod_init,   /* Module initialization function */
 	0,          /* Response function */
--- modules/usrloc/ul_mod.h	2003/04/29 18:45:23	1.1
+++ modules/usrloc/ul_mod.h	2003/04/29 18:45:47
@@ -51,6 +51,7 @@
 extern char* q_col;
 extern char* callid_col;
 extern char* cseq_col;
+extern char* user_agent_col;
 extern char* method_col;
 extern char* db_url;
 extern int   timer_interval;
--- modules/usrloc/urecord.c	2003/04/29 18:29:53	1.1
+++ modules/usrloc/urecord.c	2003/04/29 19:11:56
@@ -114,11 +114,11 @@
  *                          2) descending modification time
  */
 int mem_insert_ucontact(urecord_t* _r, str* _c, time_t _e, float _q, 
-			 str* _cid, int _cs, struct ucontact** _con)
+			 str* _cid, int _cs, str* _ua, struct ucontact** _con)
 {
 	ucontact_t* ptr, *prev = 0;
 
-	if (new_ucontact(_r->domain, &_r->aor, _c, _e, _q, _cid, _cs, _con) < 0) {
+	if (new_ucontact(_r->domain, &_r->aor, _c, _e, _q, _cid, _cs, _ua, _con) < 0) {
 		LOG(L_ERR, "mem_insert_ucontact(): Can't create new contact\n");
 		return -1;
 	}
@@ -376,9 +376,9 @@
  * Create and insert new contact
  * into urecord
  */
-int insert_ucontact(urecord_t* _r, str* _c, time_t _e, float _q, str* _cid, int _cs, struct ucontact** _con)
+int insert_ucontact(urecord_t* _r, str* _c, time_t _e, float _q, str* _cid, int _cs, str* _ua, struct ucontact** _con)
 {
-	if (mem_insert_ucontact(_r, _c, _e, _q, _cid, _cs, _con) < 0) {
+	if (mem_insert_ucontact(_r, _c, _e, _q, _cid, _cs, _ua, _con) < 0) {
 		LOG(L_ERR, "insert_ucontact(): Error while inserting contact\n");
 		return -1;
 	}
--- modules/usrloc/urecord.h	2003/04/29 18:29:12	1.1
+++ modules/usrloc/urecord.h	2003/04/29 19:10:30
@@ -80,7 +80,7 @@
  * Add a new contact
  */
 int mem_insert_ucontact(urecord_t* _r, str* _c, time_t _e, float _q, 
-			str* _cid, int _cs, struct ucontact** _con);
+			str* _cid, int _cs, str* _ua, struct ucontact** _con);
 
 
 
@@ -122,7 +122,7 @@
  * Create and insert new contact
  * into urecord
  */
-int insert_ucontact(urecord_t* _r, str* _c, time_t _e, float _q, str* _cid, int _cs, struct ucontact** _con);
+int insert_ucontact(urecord_t* _r, str* _c, time_t _e, float _q, str* _cid, int _cs, str *_ua, struct ucontact** _con);
 
 
 /*
--- modules/usrloc/usrloc.h	2003/04/29 19:29:53	1.1
+++ modules/usrloc/usrloc.h	2003/04/29 19:31:52
@@ -51,12 +51,12 @@
 
 /* urecord.h interface */
 typedef void (*release_urecord_t)  (urecord_t* _r);
-typedef int  (*insert_ucontact_t)  (urecord_t* _r, str* _c, time_t _e, float _q, str* _cid, int _cs, struct ucontact** _con);
+typedef int  (*insert_ucontact_t)  (urecord_t* _r, str* _c, time_t _e, float _q, str* _cid, int _cs, str* _ua, struct ucontact** _con);
 typedef int  (*delete_ucontact_t)  (urecord_t* _r, struct ucontact* _c);
 typedef int  (*get_ucontact_t)     (urecord_t* _r, str* _c, struct ucontact** _co);
 
 /* ucontact.h interface */
-typedef int  (*update_ucontact_t)  (ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs);
+typedef int  (*update_ucontact_t)  (ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs, str* _ua);
 
 
 struct usrloc_func {
--- modules/registrar/save.c.orig	Tue Nov 12 01:11:52 2002
+++ modules/registrar/save.c	Wed Apr 30 00:07:53 2003
@@ -106,7 +106,7 @@
  * and insert all contacts from the message that have expires
  * > 0
  */
-static inline int insert(struct sip_msg* _m, contact_t* _c, udomain_t* _d, str* _u)
+static inline int insert(struct sip_msg* _m, contact_t* _c, udomain_t* _d, str* _u, str *ua)
 {
 	urecord_t* r = 0;
 	ucontact_t* c;
@@ -153,7 +153,7 @@
 			return -4;
 		}
 
-		if (ul_insert_ucontact(r, &uri, e, q, &callid, cseq, &c) < 0) {
+		if (ul_insert_ucontact(r, &uri, e, q, &callid, cseq, ua, &c) < 0) {
 			rerrno = R_UL_INS_C;
 			LOG(L_ERR, "insert(): Error while inserting contact\n");
 			ul_delete_urecord(_d, _u);
@@ -187,7 +187,7 @@
  * 3) If contact in usrloc exists and expires
  *    == 0, delete contact
  */
-static inline int update(struct sip_msg* _m, urecord_t* _r, contact_t* _c)
+static inline int update(struct sip_msg* _m, urecord_t* _r, contact_t* _c, str* _ua)
 {
 	ucontact_t* c, *c2;
 	str uri, callid;
@@ -224,8 +224,8 @@
 					LOG(L_ERR, "update(): Error while converting cseq number\n");
 					return -3;
 				}
-				
-				if (ul_insert_ucontact(_r, &uri, e, q, &callid, cseq, &c2) < 0) {
+
+				if (ul_insert_ucontact(_r, &uri, e, q, &callid, cseq, _ua, &c2) < 0) {
 					rerrno = R_UL_INS_C;
 					LOG(L_ERR, "update(): Error while inserting contact\n");
 					return -4;
@@ -255,8 +255,8 @@
 					LOG(L_ERR, "update(): Error while converting cseq number\n");
 					return -7;
 				}
-				
-				if (ul_update_ucontact(c, e, q, &callid, cseq) < 0) {
+
+				if (ul_update_ucontact(c, e, q, &callid, cseq, _ua) < 0) {
 					rerrno = R_UL_UPD_C;
 					LOG(L_ERR, "update(): Error while updating contact\n");
 					return -8;
@@ -274,7 +274,7 @@
  * This function will process request that
  * contained some contact header fields
  */
-static inline int contacts(struct sip_msg* _m, contact_t* _c, udomain_t* _d, str* _u)
+static inline int contacts(struct sip_msg* _m, contact_t* _c, udomain_t* _d, str* _u, str* _ua)
 {
 	int res;
 	urecord_t* r;
@@ -289,7 +289,7 @@
 	}
 
 	if (res == 0) { /* Contacts found */
-		if (update(_m, r, _c) < 0) {
+		if (update(_m, r, _c, _ua) < 0) {
 			LOG(L_ERR, "contacts(): Error while updating record\n");
 			build_contact(r->contacts);
 			ul_release_urecord(r);
@@ -299,7 +299,7 @@
 		build_contact(r->contacts);
 		ul_release_urecord(r);
 	} else {
-		if (insert(_m, _c, _d, _u) < 0) {
+		if (insert(_m, _c, _d, _u, _ua) < 0) {
 			LOG(L_ERR, "contacts(): Error while inserting record\n");
 			ul_unlock_udomain(_d);
 			return -4;
@@ -309,15 +309,31 @@
 	return 0;
 }
 
+int save(struct sip_msg* _m, char* _t, char* _s)
+{
+	return save_real(_m, _t, _s, 1);
+}
+
+int save_noreply(struct sip_msg* _m, char* _t, char* _s)
+{
+	return save_real(_m, _t, _s, 0);
+}
+
+#define UA_STR "User-Agent"
+#define UA_LEN 10
+
+#define UA_DUMMY_STR "Unknown"
+#define UA_DUMMY_LEN 7
 
 /*
  * Process REGISTER request and save it's contacts
  */
-int save(struct sip_msg* _m, char* _t, char* _s)
+int save_real(struct sip_msg* _m, char* _t, char* _s, int doreply)
 {
 	contact_t* c;
 	int st;
-	str user;
+	str user, ua;
+	struct hdr_field* hf;
 
 	rerrno = R_FINE;
 
@@ -339,6 +355,20 @@
 		goto error;
 	}
 
+	ua.len = 0;
+	for (hf = _m->headers; hf != NULL; hf = hf->next) {
+		if (hf->name.len != UA_LEN ||
+		    memcmp(hf->name.s, UA_STR, hf->name.len) != 0)
+			continue;
+		ua.len = hf->body.len;
+		ua.s = hf->body.s;
+		break;
+	}
+	if (ua.len == 0) {
+		ua.len = UA_DUMMY_LEN;
+		ua.s = UA_DUMMY_STR;
+	}
+
 	if (c == 0) {
 		if (st) {
 			if (star((udomain_t*)_t, &user) < 0) goto error;
@@ -346,13 +376,13 @@
 			if (no_contacts((udomain_t*)_t, &user) < 0) goto error;
 		}
 	} else {
-		if (contacts(_m, c, (udomain_t*)_t, &user) < 0) goto error;
+		if (contacts(_m, c, (udomain_t*)_t, &user, &ua) < 0) goto error;
 	}
 
-	if (send_reply(_m) < 0) return -1;
+	if (doreply && send_reply(_m) < 0) return -1;
 	else return 1;
 	
  error:
-	send_reply(_m);
+	if (doreply) send_reply(_m);
 	return 0;
 }
--- scripts/ser_mysql.sh	2003/04/22 17:26:33	1.1
+++ scripts/ser_mysql.sh	2003/04/29 21:23:53
@@ -179,6 +179,7 @@
   callid varchar(255) default NULL,
   cseq int(11) default NULL,
   last_modified timestamp(14) NOT NULL,
+  user_agent varchar(50) NOT NULL default '',
   KEY user (user,contact)
 ) $TABLE_TYPE;
 


More information about the sr-users mailing list