Moved onto serdev(a)lists.iptel.org
Jan.
On 29-04 00:33, Maxim Sobolev wrote:
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
--- 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;