📄 exosip.c
字号:
/* eXosip - This is the eXtended osip library. Copyright (C) 2002,2003,2004,2005,2006,2007 Aymeric MOIZARD - jack@atosc.org eXosip 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. eXosip 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*/#ifdef ENABLE_MPATROL#include <mpatrol.h>#endif#include "eXosip2.h"#include <eXosip2/eXosip.h>#ifndef WIN32#if !defined(__arc__)#include <memory.h>#endif#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <unistd.h>#endif/* Private functions */static jauthinfo_t *eXosip_find_authentication_info (const char *username, const char *realm);eXosip_t eXosip;#ifdef OSIP_MTvoid__eXosip_wakeup (void){ jpipe_write (eXosip.j_socketctl, "w", 1);}void__eXosip_wakeup_event (void){ jpipe_write (eXosip.j_socketctl_event, "w", 1);}inteXosip_lock (void){ return osip_mutex_lock ((struct osip_mutex *) eXosip.j_mutexlock);}inteXosip_unlock (void){ return osip_mutex_unlock ((struct osip_mutex *) eXosip.j_mutexlock);}#endifint_eXosip_transaction_init (osip_transaction_t ** transaction, osip_fsm_type_t ctx_type, osip_t * osip, osip_message_t * message){#ifdef SRV_RECORD osip_srv_record_t record;#endif int i; i = osip_transaction_init (transaction, ctx_type, osip, message); if (i != 0) { return i; }#ifdef SRV_RECORD memset (&record, 0, sizeof (osip_srv_record_t)); i = _eXosip_srv_lookup (*transaction, message, &record); if (i < 0) { /* might be a simple DNS request or an IP */ return OSIP_SUCCESS; } osip_transaction_set_srv_record (*transaction, &record);#endif return OSIP_SUCCESS;}inteXosip_transaction_find (int tid, osip_transaction_t ** transaction){ int pos = 0; *transaction = NULL; while (!osip_list_eol (&eXosip.j_transactions, pos)) { osip_transaction_t *tr; tr = (osip_transaction_t *) osip_list_get (&eXosip.j_transactions, pos); if (tr->transactionid == tid) { *transaction = tr; return OSIP_SUCCESS; } pos++; } return OSIP_NOTFOUND;}#ifndef MINISIZEstatic int_eXosip_retry_with_auth (eXosip_dialog_t * jd, osip_transaction_t ** ptr, int *retry){ osip_transaction_t *out_tr = NULL; osip_transaction_t *tr = NULL; osip_message_t *msg = NULL; osip_event_t *sipevent; jinfo_t *ji = NULL; int cseq; osip_via_t *via; int i; if (!ptr) return OSIP_BADPARAMETER; if (jd != NULL) { if (jd->d_out_trs == NULL) return OSIP_UNDEFINED_ERROR; } out_tr = *ptr; if (out_tr == NULL || out_tr->orig_request == NULL || out_tr->last_response == NULL) return OSIP_BADPARAMETER; if (retry && (*retry >= 3)) return OSIP_UNDEFINED_ERROR; i = osip_message_clone (out_tr->orig_request, &msg); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: could not clone msg for authentication\n")); return i; } via = (osip_via_t *) osip_list_get (&msg->vias, 0); if (via == NULL || msg->cseq == NULL || msg->cseq->number == NULL) { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing via or cseq header\n")); return OSIP_SYNTAXERROR; } /* increment cseq */ cseq = atoi (msg->cseq->number); osip_free (msg->cseq->number); msg->cseq->number = strdup_printf ("%i", cseq + 1); if (jd != NULL && jd->d_dialog != NULL) { jd->d_dialog->local_cseq++; } i = eXosip_update_top_via (msg); if (i != 0) { osip_message_free (msg); return i; } osip_list_special_free (&msg->authorizations, (void *(*)(void *)) &osip_authorization_free); osip_list_special_free (&msg->proxy_authorizations, (void *(*)(void *)) &osip_proxy_authorization_free); if (out_tr != NULL && out_tr->last_response != NULL && (out_tr->last_response->status_code == 401 || out_tr->last_response->status_code == 407)) { i = eXosip_add_authentication_information (msg, out_tr->last_response); if (i < 0) { osip_message_free (msg); return i; } } else { i = eXosip_add_authentication_information (msg, NULL); if (i < 0) { osip_message_free (msg); return i; } } osip_message_force_update (msg); if (MSG_IS_INVITE (msg)) i = _eXosip_transaction_init (&tr, ICT, eXosip.j_osip, msg); else i = _eXosip_transaction_init (&tr, NICT, eXosip.j_osip, msg); if (i != 0) { osip_message_free (msg); return i; } /* replace with the new tr */ if (MSG_IS_PUBLISH (msg)) { /* old transaction is put in the garbage list */ osip_list_add (&eXosip.j_transactions, out_tr, 0); /* new transaction is put in the publish context */ *ptr = tr; } else osip_list_add (&eXosip.j_transactions, tr, 0); sipevent = osip_new_outgoing_sipmessage (msg); ji = osip_transaction_get_your_instance (out_tr); osip_transaction_set_your_instance (out_tr, NULL); osip_transaction_set_your_instance (tr, ji); osip_transaction_add_event (tr, sipevent); if (retry) (*retry)++; eXosip_update (); /* fixed? */ __eXosip_wakeup (); return OSIP_SUCCESS;}static int_eXosip_publish_refresh (eXosip_dialog_t * jd, osip_transaction_t ** ptr, int *retry){ osip_transaction_t *out_tr = NULL; osip_transaction_t *tr = NULL; osip_message_t *msg = NULL; osip_event_t *sipevent; jinfo_t *ji = NULL; int cseq; osip_via_t *via; int i; if (!ptr) return OSIP_BADPARAMETER; if (jd != NULL) { if (jd->d_out_trs == NULL) return OSIP_BADPARAMETER; } out_tr = *ptr; if (out_tr == NULL || out_tr->orig_request == NULL || out_tr->last_response == NULL) return OSIP_BADPARAMETER; if (retry && (*retry >= 3)) return OSIP_UNDEFINED_ERROR; i = osip_message_clone (out_tr->orig_request, &msg); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: could not clone msg for authentication\n")); return i; } via = (osip_via_t *) osip_list_get (&msg->vias, 0); if (via == NULL || msg->cseq == NULL || msg->cseq->number == NULL) { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing via or cseq header\n")); return OSIP_SYNTAXERROR; } /* increment cseq */ cseq = atoi (msg->cseq->number); osip_free (msg->cseq->number); msg->cseq->number = strdup_printf ("%i", cseq + 1); if (msg->cseq->number == NULL) { osip_message_free (msg); return OSIP_NOMEM; } if (jd != NULL && jd->d_dialog != NULL) { jd->d_dialog->local_cseq++; } i = eXosip_update_top_via (msg); if (i != 0) { osip_message_free (msg); return i; } osip_list_special_free (&msg->authorizations, (void *(*)(void *)) &osip_authorization_free); osip_list_special_free (&msg->proxy_authorizations, (void *(*)(void *)) &osip_proxy_authorization_free); if (out_tr != NULL && out_tr->last_response != NULL && (out_tr->last_response->status_code == 401 || out_tr->last_response->status_code == 407)) { eXosip_add_authentication_information (msg, out_tr->last_response); } else eXosip_add_authentication_information (msg, NULL); if (out_tr != NULL && out_tr->last_response != NULL && out_tr->last_response->status_code == 412) { /* remove SIP-If-Match header */ int pos = 0; while (!osip_list_eol (&msg->headers, pos)) { osip_header_t *head = osip_list_get (&msg->headers, pos); if (head != NULL && 0 == osip_strcasecmp (head->hname, "sip-if-match")) { i = osip_list_remove (&msg->headers, pos); osip_header_free (head); break; } pos++; } } if (out_tr != NULL && out_tr->last_response != NULL && out_tr->last_response->status_code == 423) { /* increase expires value to "min-expires" value */ osip_header_t *exp; osip_header_t *min_exp; osip_message_header_get_byname (msg, "expires", 0, &exp); osip_message_header_get_byname (out_tr->last_response, "min-expires", 0, &min_exp); if (exp != NULL && exp->hvalue != NULL && min_exp != NULL && min_exp->hvalue != NULL) { osip_free (exp->hvalue); exp->hvalue = osip_strdup (min_exp->hvalue); } else { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing Min-Expires or Expires in PUBLISH\n")); return OSIP_SYNTAXERROR; } } osip_message_force_update (msg); if (MSG_IS_INVITE (msg)) i = _eXosip_transaction_init (&tr, ICT, eXosip.j_osip, msg); else i = _eXosip_transaction_init (&tr, NICT, eXosip.j_osip, msg); if (i != 0) { osip_message_free (msg); return i; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -