--- 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 /* abort */ #include /* strlen, memcmp */ #include /* 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;