⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 register.c

📁 sip proxy
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Copyright (C) 2002-2005  Thomas Ries <tries@gmx.net>    This file is part of Siproxd.        Siproxd 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.        Siproxd 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 Siproxd; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "config.h"#include <stdio.h>#include <time.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#include <osipparser2/osip_parser.h>#include "siproxd.h"#include "log.h"static char const ident[]="$Id: register.c,v 1.60 2006/10/13 17:40:09 hb9xar Exp $";/* configuration storage */extern struct siproxd_config configuration;/* URL mapping table     */struct urlmap_s urlmap[URLMAP_SIZE];/* time of last save     */static time_t last_save=0;extern int errno;/* * initialize the URL mapping table */void register_init(void) {   FILE *stream;   int sts, i;   size_t len;   char buff[128];   memset(urlmap, 0, sizeof(urlmap));   if (configuration.registrationfile) {      stream = fopen(configuration.registrationfile, "r");      if (!stream) {         /*          * the file does not exist, or the size was incorrect,          * delete it and start from scratch          */         unlink(configuration.registrationfile);         WARN("registration file not found, starting with empty table");      } else {         /* read the url table from file */         for (i=0;i < URLMAP_SIZE; i++) {            fgets(buff, sizeof(buff), stream);            sts=sscanf(buff, "***:%i:%i", &urlmap[i].active, &urlmap[i].expires);            if (sts == 0) break; /* format error */            if (urlmap[i].active) {               osip_uri_init(&urlmap[i].true_url);               osip_uri_init(&urlmap[i].masq_url);               osip_uri_init(&urlmap[i].reg_url);               #define R(X) {\               fgets(buff, sizeof(buff), stream);\               buff[sizeof(buff)-1]='\0';\               if (strchr(buff, 10)) *strchr(buff, 10)='\0';\               if (strchr(buff, 13)) *strchr(buff, 13)='\0';\               if (strlen(buff) > 0) {\                  len  = strlen(buff);\                  X    =(char*)malloc(len+1);\                  sts=sscanf(buff,"%s",X);\                  if (sts == 0) break;\               } else {\                  X = NULL;\               }\               }               R(urlmap[i].true_url->scheme);               R(urlmap[i].true_url->username);               R(urlmap[i].true_url->host);               R(urlmap[i].true_url->port);               R(urlmap[i].masq_url->scheme);               R(urlmap[i].masq_url->username);               R(urlmap[i].masq_url->host);               R(urlmap[i].masq_url->port);               R(urlmap[i].reg_url->scheme);               R(urlmap[i].reg_url->username);               R(urlmap[i].reg_url->host);               R(urlmap[i].reg_url->port);            }         }         fclose(stream);         /* check for premature abort of reading the registration file */         if (i < URLMAP_SIZE) {            /* clean up and delete it */            WARN("registration file corrupt, starting with empty table");            memset(urlmap, 0, sizeof(urlmap));            unlink(configuration.registrationfile);         }      }   }   /* initialize save-timer */   time(&last_save);   return;}/* * shut down the URL mapping table */void register_save(void) {   int i;   FILE *stream;   if (configuration.registrationfile) {      /* write urlmap back to file */      stream = fopen(configuration.registrationfile, "w+");      if (!stream) {         /* try to unlink it and open again */         unlink(configuration.registrationfile);         stream = fopen(configuration.registrationfile, "w+");         /* open file for write failed, complain */         if (!stream) {            ERROR("unable to write registration file");            return;         }      }      for (i=0;i < URLMAP_SIZE; i++) {         fprintf(stream, "***:%i:%i\n", urlmap[i].active, urlmap[i].expires);         if (urlmap[i].active) {            #define W(X) fprintf(stream, "%s\n", (X)? X:"");            W(urlmap[i].true_url->scheme);            W(urlmap[i].true_url->username);            W(urlmap[i].true_url->host);            W(urlmap[i].true_url->port);            W(urlmap[i].masq_url->scheme);            W(urlmap[i].masq_url->username);            W(urlmap[i].masq_url->host);            W(urlmap[i].masq_url->port);            W(urlmap[i].reg_url->scheme);            W(urlmap[i].reg_url->username);            W(urlmap[i].reg_url->host);            W(urlmap[i].reg_url->port);         }      }      fclose(stream);   }   return;}/* * handles register requests and updates the URL mapping table * * RETURNS: *    STS_SUCCESS : successfully registered *    STS_FAILURE : registration failed *    STS_NEED_AUTH : authentication needed */int register_client(sip_ticket_t *ticket, int force_lcl_masq) {   int i, j, n, sts;   int expires;   time_t time_now;   osip_contact_t *contact;   osip_uri_t *url1_to, *url1_contact=NULL;   osip_uri_t *url2_to;   osip_header_t *expires_hdr;   osip_uri_param_t *expires_param=NULL;      /*    * Authorization - do only if I'm not just acting as outbound proxy    * but am ment to be the registrar    */   if (force_lcl_masq == 0) {      /*       * RFC 3261, Section 16.3 step 6       * Proxy Behavior - Request Validation - Proxy-Authorization       */      sts = authenticate_proxy(ticket->sipmsg);      if (sts == STS_FAILURE) {         /* failed */         WARN("proxy authentication failed for %s@%s",              (ticket->sipmsg->to->url->username)?               ticket->sipmsg->to->url->username : "*NULL*",              ticket->sipmsg->to->url->host);         return STS_FAILURE;      } else if (sts == STS_NEED_AUTH) {         /* needed */         DEBUGC(DBCLASS_REG,"proxy authentication needed for %s@%s",                ticket->sipmsg->to->url->username,                ticket->sipmsg->to->url->host);         return STS_NEED_AUTH;      }   }/*   fetch 1st Via entry and remember this address. Incoming requests   for the registered address have to be passed on to that host.   To: -> address to be registered   Contact: -> host is reachable there               Note: in case of un-REGISTER, the contact header may                     contain '*' only - which means "all registrations                     made by this UA"      => Mapping is   To: <1--n> Contact   */   time(&time_now);   DEBUGC(DBCLASS_BABBLE,"sip_register:");   /*    * First make sure, we have a proper Contact header:    *  - url    *  - url -> hostname    *    * Libosip parses an:    * "Contact: *"    * the following way (Note: Display name!! and URL is NULL)    * (gdb) p *((osip_contact_t*)(sip->contacts->node->element))    * $5 = {displayname = 0x8af8848 "*", url = 0x0, gen_params = 0x8af8838}    */   osip_message_get_contact(ticket->sipmsg, 0, &contact);   if ((contact == NULL) ||       (contact->url == NULL) ||       (contact->url->host == NULL)) {      /* Don't have required Contact fields.         This may be a Registration query or unregistering all registered         records for this UA. We should simply forward this request to its         destination. However, if this is an unregistration from a client         that is not registered (Grandstream "unregister at startup" option)         -> How do I handle this one?         Right now we do a direction lookup and if this fails we generate         an OK message by ourself (fake) */      DEBUGC(DBCLASS_REG, "empty Contact header - "             "seems to be a registration query");      sts = sip_find_direction(ticket, NULL);      if (sts != STS_SUCCESS) {         /* answer the request myself. Most likely this is an UNREGISTER          * request when the client just booted */         sts = register_response(ticket, STS_SUCCESS);         return STS_SIP_SENT;      }      return STS_SUCCESS;   }   url1_contact=contact->url;   /* evaluate Expires Header field */   osip_message_get_expires(ticket->sipmsg, 0, &expires_hdr);  /*   * look for an Contact expires parameter - in case of REGISTER   * these two are equal. The Contact expires has higher priority!   */   if (ticket->sipmsg->contacts && ticket->sipmsg->contacts->node &&       ticket->sipmsg->contacts->node->element) {      osip_contact_param_get_byname(              (osip_contact_t*) ticket->sipmsg->contacts->node->element,              EXPIRES, &expires_param);   }   if (expires_param && expires_param->gvalue) {      /* get expires from contact Header */      expires=atoi(expires_param->gvalue);      if ((expires < 0) || (expires >= LONG_MAX))         expires=configuration.default_expires;   } else if (expires_hdr && expires_hdr->hvalue) {      /* get expires from expires Header */      expires=atoi(expires_hdr->hvalue);      if ((expires < 0) || (expires >= LONG_MAX))         expires=configuration.default_expires;   } else {      char tmp[16];      /* it seems, the expires field is not present everywhere... */      DEBUGC(DBCLASS_REG,"no 'expires' header found - set time to %i sec",             configuration.default_expires);      expires=configuration.default_expires;      sprintf(tmp,"%i",expires);      osip_message_set_expires(ticket->sipmsg, tmp);   }   url1_to=ticket->sipmsg->to->url;   /*    * REGISTER    */   if (expires > 0) {      DEBUGC(DBCLASS_REG,"register: %s@%s expires=%i seconds",          (url1_contact->username) ? url1_contact->username : "*NULL*",          (url1_contact->host) ? url1_contact->host : "*NULL*",          expires);      /*       * Update registration. There are two possibilities:       * - already registered, then update the existing record       * - not registered, then create a new record       */      j=-1;      for (i=0; i<URLMAP_SIZE; i++) {         if (urlmap[i].active == 0) {            if (j < 0) j=i; /* remember first hole */            continue;         }         url2_to=urlmap[i].reg_url;         /* check address-of-record ("public address" of user) */         if (compare_url(url1_to, url2_to)==STS_SUCCESS) {            DEBUGC(DBCLASS_REG, "found entry for %s@%s <-> %s@%s at "                   "slot=%i, exp=%li",                   (url1_contact->username) ? url1_contact->username : "*NULL*",                   (url1_contact->host) ? url1_contact->host : "*NULL*",                   (url2_to->username) ? url2_to->username : "*NULL*",                   (url2_to->host) ? url2_to->host : "*NULL*",                   i, (long)urlmap[i].expires-time_now);            break;         }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -