udp.c

来自「libosip2-3版本的osip源代码」· C语言 代码 · 共 1,949 行 · 第 1/5 页

C
1,949
字号
/*  eXosip - This is the eXtended osip library.  Copyright (C) 2002, 2003  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#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#ifdef __APPLE_CC__#include <unistd.h>#endif#else#include <windows.h>#endifextern eXosip_t eXosip;extern int ipv6_enable;/* Private functions */static void eXosip_send_default_answer (eXosip_dialog_t * jd,                                        osip_transaction_t * transaction,                                        osip_event_t * evt,                                        int status,                                        char *reason_phrase,                                        char *warning, int line);static void eXosip_process_info (eXosip_call_t * jc, eXosip_dialog_t * jd,                                 osip_transaction_t * transaction,                                 osip_event_t * evt);static void eXosip_process_options (eXosip_call_t * jc, eXosip_dialog_t * jd,                                    osip_transaction_t * transaction,                                    osip_event_t * evt);static void eXosip_process_bye (eXosip_call_t * jc, eXosip_dialog_t * jd,                                osip_transaction_t * transaction,                                osip_event_t * evt);static void eXosip_process_refer (eXosip_call_t * jc, eXosip_dialog_t * jd,                                  osip_transaction_t * transaction,                                  osip_event_t * evt);static void eXosip_process_ack (eXosip_call_t * jc, eXosip_dialog_t * jd,                                osip_event_t * evt);static void eXosip_process_prack (eXosip_call_t * jc, eXosip_dialog_t * jd,                                  osip_transaction_t * transaction,                                  osip_event_t * evt);static int cancel_match_invite (osip_transaction_t * invite,                                osip_message_t * cancel);static void eXosip_process_cancel (osip_transaction_t * transaction,                                   osip_event_t * evt);static osip_event_t *eXosip_process_reinvite (eXosip_call_t * jc,                                              eXosip_dialog_t * jd,                                              osip_transaction_t *                                              transaction, osip_event_t * evt);static void eXosip_process_new_options (osip_transaction_t * transaction,                                        osip_event_t * evt);static void eXosip_process_new_invite (osip_transaction_t * transaction,                                       osip_event_t * evt);static void eXosip_process_new_subscribe (osip_transaction_t * transaction,                                          osip_event_t * evt);static void eXosip_process_subscribe_within_call (eXosip_notify_t * jn,                                                  eXosip_dialog_t * jd,                                                  osip_transaction_t *                                                  transaction, osip_event_t * evt);static void eXosip_process_notify_within_dialog (eXosip_subscribe_t * js,                                                 eXosip_dialog_t * jd,                                                 osip_transaction_t *                                                 transaction, osip_event_t * evt);static int eXosip_match_notify_for_subscribe (eXosip_subscribe_t * js,                                              osip_message_t * notify);static void eXosip_process_message_outside_of_dialog (osip_transaction_t * tr,                                                      osip_event_t * evt);static void eXosip_process_refer_outside_of_dialog (osip_transaction_t * tr,                                                    osip_event_t * evt);static void eXosip_process_message_within_dialog (eXosip_call_t * jc,                                                  eXosip_dialog_t * jd,                                                  osip_transaction_t *                                                  transaction, osip_event_t * evt);static void eXosip_process_newrequest (osip_event_t * evt, int socket);static void eXosip_process_response_out_of_transaction (osip_event_t * evt);static int eXosip_pendingosip_transaction_exist (eXosip_call_t * jc,                                                 eXosip_dialog_t * jd);static int eXosip_release_finished_calls (eXosip_call_t * jc,                                          eXosip_dialog_t * jd);static int eXosip_release_aborted_calls (eXosip_call_t * jc, eXosip_dialog_t * jd);static int eXosip_release_finished_transactions (eXosip_call_t *jc, eXosip_dialog_t * jd);static int eXosip_release_finished_transactions_for_subscription (eXosip_dialog_t *jd);static voideXosip_send_default_answer (eXosip_dialog_t * jd,                            osip_transaction_t * transaction,                            osip_event_t * evt,                            int status,                            char *reason_phrase, char *warning, int line){  osip_event_t *evt_answer;  osip_message_t *answer;  int i;  /* osip_list_add(eXosip.j_transactions, transaction, 0); */  osip_transaction_set_your_instance (transaction, NULL);  /* THIS METHOD DOES NOT ACCEPT STATUS CODE BETWEEN 101 and 299 */  if (status > 100 && status < 299 && MSG_IS_INVITE (evt->sip))    return;  if (jd != NULL)    i = _eXosip_build_response_default (&answer, jd->d_dialog, status, evt->sip);  else    i = _eXosip_build_response_default (&answer, NULL, status, evt->sip);  if (i != 0 || answer == NULL)    {      return;    }  if (reason_phrase != NULL)    {      char *_reason;      _reason = osip_message_get_reason_phrase (answer);      if (_reason != NULL)        osip_free (_reason);      _reason = osip_strdup (reason_phrase);      osip_message_set_reason_phrase (answer, _reason);    }  osip_message_set_content_length (answer, "0");  if (status == 500)    osip_message_set_retry_after (answer, "10");  evt_answer = osip_new_outgoing_sipmessage (answer);  evt_answer->transactionid = transaction->transactionid;  osip_transaction_add_event (transaction, evt_answer);  __eXosip_wakeup ();}static voideXosip_process_options (eXosip_call_t * jc, eXosip_dialog_t * jd,                        osip_transaction_t * transaction, osip_event_t * evt){  osip_list_add (jd->d_inc_trs, transaction, 0);  osip_transaction_set_your_instance (transaction,                                      __eXosip_new_jinfo (jc, jd, NULL, NULL));  __eXosip_wakeup ();}static voideXosip_process_info (eXosip_call_t * jc, eXosip_dialog_t * jd,                     osip_transaction_t * transaction, osip_event_t * evt){  osip_list_add (jd->d_inc_trs, transaction, 0);  osip_transaction_set_your_instance (transaction,                                      __eXosip_new_jinfo (jc, jd, NULL, NULL));  __eXosip_wakeup ();}static voideXosip_process_bye (eXosip_call_t * jc, eXosip_dialog_t * jd,                    osip_transaction_t * transaction, osip_event_t * evt){  osip_event_t *evt_answer;  osip_message_t *answer;  int i;  osip_transaction_set_your_instance (transaction,                                      __eXosip_new_jinfo (jc, NULL /*jd */ ,                                                          NULL, NULL));  i = _eXosip_build_response_default (&answer, jd->d_dialog, 200, evt->sip);  if (i != 0)    {      osip_list_add (eXosip.j_transactions, transaction, 0);      return;    }  osip_message_set_content_length (answer, "0");  evt_answer = osip_new_outgoing_sipmessage (answer);  evt_answer->transactionid = transaction->transactionid;  osip_list_add (jd->d_inc_trs, transaction, 0);  /* Release the eXosip_dialog */  osip_dialog_free (jd->d_dialog);  jd->d_dialog = NULL;  osip_transaction_add_event (transaction, evt_answer);  osip_nist_execute (eXosip.j_osip);  report_call_event (EXOSIP_CALL_MESSAGE_NEW, jc, jd, transaction);  report_call_event (EXOSIP_CALL_CLOSED, jc, jd, transaction);  eXosip_update ();             /* AMD 30/09/05 */  __eXosip_wakeup ();}static voideXosip_process_refer (eXosip_call_t * jc, eXosip_dialog_t * jd,                      osip_transaction_t * transaction, osip_event_t * evt){  osip_header_t *referto_head = NULL;  osip_contact_t *referto;  int i;  /* check if the refer is valid */  osip_message_header_get_byname (evt->sip, "refer-to", 0, &referto_head);  if (referto_head == NULL || referto_head->hvalue == NULL)    {      osip_list_add (eXosip.j_transactions, transaction, 0);      eXosip_send_default_answer (jd, transaction, evt, 400,                                  "Missing Refer-To header",                                  "Missing Refer-To header", __LINE__);      return;    }  /* check if refer-to is well-formed */  osip_contact_init (&referto);  i = osip_contact_parse (referto, referto_head->hvalue);  if (i != 0)    {      osip_contact_free (referto);      osip_list_add (eXosip.j_transactions, transaction, 0);      eXosip_send_default_answer (jd, transaction, evt, 400,                                  "Non valid Refer-To header",                                  "Non valid Refer-To header", __LINE__);      return;    }  osip_contact_free (referto);  /* check policy so we can decline immediatly the refer */  osip_transaction_set_your_instance (transaction,                                      __eXosip_new_jinfo (jc, jd, NULL, NULL));  osip_list_add (jd->d_inc_trs, transaction, 0);  __eXosip_wakeup ();}static voideXosip_process_notify_for_refer (eXosip_call_t * jc, eXosip_dialog_t * jd,                                 osip_transaction_t * transaction,                                 osip_event_t * evt){#if 0  osip_event_t *evt_answer;  osip_message_t *answer;  int i;  osip_transaction_t *ref;  osip_header_t *event_hdr;  osip_header_t *sub_state;  osip_content_type_t *ctype;  osip_body_t *body = NULL;  /* get the event type and return "489 Bad Event". */  osip_message_header_get_byname (evt->sip, "event", 0, &event_hdr);  if (event_hdr == NULL || event_hdr->hvalue == NULL)    {      osip_list_add (eXosip.j_transactions, transaction, 0);      eXosip_send_default_answer (jd, transaction, evt, 400,                                  "Missing Event header in Notify",                                  "Missing Event header in Notify", __LINE__);      return;    }  if (NULL == strstr (event_hdr->hvalue, "refer"))    {      osip_list_add (eXosip.j_transactions, transaction, 0);      eXosip_send_default_answer (jd, transaction, evt, 501,                                  "Unsupported Event header",                                  "Unsupported Event header in Notify", __LINE__);      return;    }  osip_message_header_get_byname (evt->sip, "subscription-state", 0, &sub_state);  if (sub_state == NULL || sub_state->hvalue == NULL)    {#ifndef CISCO_BUG      osip_list_add (eXosip.j_transactions, transaction, 0);      eXosip_send_default_answer (jd, transaction, evt, 400, "Missing Header",                                  "Missing subscription-state Header", __LINE__);      return;#else      OSIP_TRACE (osip_trace                  (__FILE__, __LINE__, OSIP_WARNING, NULL,                   "eXosip: Missing subscription-state Header (cisco 7960 bug)\n"));#endif    }  ctype = osip_message_get_content_type (evt->sip);  if (ctype == NULL || ctype->type == NULL || ctype->subtype == NULL)    {      osip_list_add (eXosip.j_transactions, transaction, 0);      eXosip_send_default_answer (jd, transaction, evt, 400, "Missing Header",                                  "Missing Content-Type Header", __LINE__);      return;    }  if (0 != osip_strcasecmp (ctype->type, "message")      || 0 != osip_strcasecmp (ctype->subtype, "sipfrag"))    {      osip_list_add (eXosip.j_transactions, transaction, 0);      eXosip_send_default_answer (jd, transaction, evt, 501,                                  "Unsupported body type",                                  "Unsupported body type", __LINE__);      return;    }  osip_message_get_body (evt->sip, 0, &body);  if (body == NULL || body->body == NULL)    {      osip_list_add (eXosip.j_transactions, transaction, 0);      eXosip_send_default_answer (jd, transaction, evt, 400, "Missing Body",                                  "Missing Body", __LINE__);      return;    }#if 0  report_call_event (EXOSIP_CALL_REFER_STATUS, jc, jd, transaction);#endif  /* check if a refer was sent previously! */  ref = eXosip_find_last_out_transaction (jc, jd, "REFER");  if (ref == NULL)    {      osip_list_add (eXosip.j_transactions, transaction, 0);      eXosip_send_default_answer (jd, transaction, evt, 481, NULL,                                  "No associated refer", __LINE__);      return;    }  osip_transaction_set_your_instance (transaction,                                      __eXosip_new_jinfo (jc, jd, NULL, NULL));  /* for now, send default response of 200ok.  eventually, application should     be deciding how to answer NOTIFY messages */  i = _eXosip_build_response_default (&answer, jd->d_dialog, 200, evt->sip);  if (i != 0)    {      osip_list_add (eXosip.j_transactions, transaction, 0);      return;    }  i = complete_answer_that_establish_a_dialog (answer, evt->sip);  evt_answer = osip_new_outgoing_sipmessage (answer);  evt_answer->transactionid = transaction->transactionid;  osip_list_add (jd->d_inc_trs, transaction, 0);  osip_transaction_add_event (transaction, evt_answer);  __eXosip_wakeup ();#else  osip_list_add (jd->d_inc_trs, transaction, 0);  osip_transaction_set_your_instance (transaction,                                      __eXosip_new_jinfo (jc, jd, NULL, NULL));  __eXosip_wakeup ();#endif}static voideXosip_process_ack (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_event_t * evt){  /* TODO: We should find the matching transaction for this ACK     and also add the ACK in the event. */  eXosip_event_t *je;  int i;  /* stop ACK retransmission, in case there is any */  jd->d_count=0;  osip_message_free(jd->d_200Ok);  jd->d_200Ok=NULL;

⌨️ 快捷键说明

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