📄 ucontact.c
字号:
/* * $Id: ucontact.c,v 1.32.2.4 2005/07/27 12:40:31 janakj Exp $ * * Usrloc contact structure * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of ser, a free SIP server. * * ser is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: * info@iptel.org * * ser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * History: * --------- * 2003-03-12 added replication mark and three zombie states (nils) * 2004-03-17 generic callbacks added (bogdan) * 2004-06-07 updated to the new DB api (andrei) */#include "ucontact.h"#include <string.h> /* memcpy */#include "../../mem/shm_mem.h"#include "../../ut.h"#include "../../dprint.h"#include "../../db/db.h"#include "ul_mod.h"#include "ul_callback.h"/* * Create a new contact structure */int new_ucontact(str* _dom, str* _aor, str* _contact, time_t _e, qvalue_t _q, str* _callid, int _cseq, unsigned int _flags, ucontact_t** _c, str* _ua, str* _recv){ *_c = (ucontact_t*)shm_malloc(sizeof(ucontact_t)); if (!(*_c)) { LOG(L_ERR, "new_ucontact(): No memory left\n"); return -1; } memset(*_c, 0, sizeof(ucontact_t)); (*_c)->domain = _dom; (*_c)->aor = _aor; (*_c)->c.s = (char*)shm_malloc(_contact->len); if ((*_c)->c.s == 0) { LOG(L_ERR, "new_ucontact(): No memory left 2\n"); goto error; } memcpy((*_c)->c.s, _contact->s, _contact->len); (*_c)->c.len = _contact->len; (*_c)->expires = _e; (*_c)->q = _q; (*_c)->callid.s = (char*)shm_malloc(_callid->len); if ((*_c)->callid.s == 0) { LOG(L_ERR, "new_ucontact(): No memory left 4\n"); goto error; } 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"); goto error; } memcpy((*_c)->user_agent.s, _ua->s, _ua->len); (*_c)->user_agent.len = _ua->len; if (_recv) { (*_c)->received.s = (char*)shm_malloc(_recv->len); if ((*_c)->received.s == 0) { LOG(L_ERR, "new_ucontact(): No memory left\n"); goto error; } memcpy((*_c)->received.s, _recv->s, _recv->len); (*_c)->received.len = _recv->len; } else { (*_c)->received.s = 0; (*_c)->received.len = 0; } (*_c)->cseq = _cseq; (*_c)->state = CS_NEW; (*_c)->flags = _flags; return 0; error: if (*_c) { if ((*_c)->received.s) shm_free((*_c)->received.s); if ((*_c)->user_agent.s) shm_free((*_c)->user_agent.s); if ((*_c)->callid.s) shm_free((*_c)->callid.s); if ((*_c)->c.s) shm_free((*_c)->c.s); shm_free(*_c); } return -1;} /* * Free all memory associated with given contact structure */void free_ucontact(ucontact_t* _c){ if (!_c) return; if (_c->received.s) shm_free(_c->received.s); if (_c->user_agent.s) shm_free(_c->user_agent.s); if (_c->callid.s) shm_free(_c->callid.s); if (_c->c.s) shm_free(_c->c.s); shm_free(_c);}/* * Print contact, for debugging purposes only */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->flags & FL_PERMANENT) { fprintf(_f, "Permanent\n"); } else { if (_c->expires == 0) { 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, "State : %s\n", st); fprintf(_f, "Flags : %u\n", _c->flags); fprintf(_f, "next : %p\n", _c->next); fprintf(_f, "prev : %p\n", _c->prev); fprintf(_f, "~~~/Contact~~~~\n");}/* * Update ucontact structure in memory */int mem_update_ucontact(ucontact_t* _c, time_t _e, qvalue_t _q, str* _cid, int _cs, unsigned int _set, unsigned int _res, str* _ua, str* _recv){ char* ptr; if (_c->callid.len < _cid->len) { ptr = (char*)shm_malloc(_cid->len); if (ptr == 0) { LOG(L_ERR, "update_ucontact(): No memory left\n"); return -1; } memcpy(ptr, _cid->s, _cid->len); shm_free(_c->callid.s); _c->callid.s = ptr; } else { 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; if (_recv) { if (_c->received.len < _recv->len) { ptr = (char*)shm_malloc(_recv->len); if (ptr == 0) { LOG(L_ERR, "update_ucontact(): No memory left\n"); return -1; } memcpy(ptr, _recv->s, _recv->len); /* previous received might be NULL! -bogdan */ if (_c->received.s) shm_free(_c->received.s); _c->received.s = ptr; } else { memcpy(_c->received.s, _recv->s, _recv->len); } _c->received.len = _recv->len; } else { if (_c->received.s) shm_free(_c->received.s); _c->received.s = 0; _c->received.len = 0; } _c->expires = _e; _c->q = _q; _c->cseq = _cs; _c->flags |= _set; _c->flags &= ~_res; return 0;}/* ================ State related functions =============== *//* * Update state of the contact */void st_update_ucontact(ucontact_t* _c){ switch(_c->state) { case CS_NEW: /* Contact is new and is not in the database yet, * we remain in the same state here because the * contact must be inserted later in the timer */ break; case CS_SYNC: /* For db mode 2 a modified contact needs to be * updated also in the database, so transit into * CS_DIRTY and let the timer to do the update * again. For db mode 1 the db update is already * done and we don't have to change the state. */ if (db_mode == WRITE_BACK) { _c->state = CS_DIRTY; } break; case CS_DIRTY: /* Modification of dirty contact results in * dirty contact again, don't change anything */ break; }}/* * Update state of the contact * Returns 1 if the contact should be * delete from memory immediately, * 0 otherwise */int st_delete_ucontact(ucontact_t* _c){ switch(_c->state) { case CS_NEW: /* Contact is new and isn't in the database * yet, we can delete it from the memory * safely. */ return 1; case CS_SYNC: case CS_DIRTY: /* Contact is in the database, * we cannot remove it from the memory * directly, but we can set expires to zero * and the timer will take care of deleting * the contact from the memory as well as * from the database */ if (db_mode == WRITE_BACK) { /* Reset permanent flag */ _c->flags &= ~FL_PERMANENT; _c->expires = 0; return 0; } else { /* WRITE_THROUGH or NO_DB -- we can * remove it from memory immediately and * the calling function would also remove * it from the database if needed */ return 1; } } return 0; /* Makes gcc happy */}/* * Called when the timer is about to delete * an expired contact, this routine returns * 1 if the contact should be removed from * the database and 0 otherwise */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -