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

📄 extl_dtls.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  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 "eXtransport.h"#ifdef HAVE_OPENSSL_SSL_H#include <openssl/ssl.h>#if !(OPENSSL_VERSION_NUMBER < 0x00908000L)#define SPROTO_TLS 500#define SPROTO_DTLS 501#include <openssl/ssl.h>#include <openssl/err.h>#include <openssl/pem.h>#include <openssl/x509.h>#include <openssl/rand.h>#define SSLDEBUG 1#define PASSWORD "password"#define CLIENT_KEYFILE "ckey.pem"#define CLIENT_CERTFILE "c.pem"#define SERVER_KEYFILE "skey.pem"#define SERVER_CERTFILE "s.pem"#define CA_LIST "cacert.pem"#define RANDOM  "random.pem"#define DHFILE "dh1024.pem"#if defined(_WIN32_WCE)#define strerror(X) "-1"#endif#ifdef _WIN32_WCE#include "inet_ntop.h"#elif WIN32#include "inet_ntop.h"#endifSSL_CTX *initialize_client_ctx (const char *keyfile, const char *certfile,                                const char *password, int transport);SSL_CTX *initialize_server_ctx (const char *keyfile, const char *certfile,                                const char *password, int transport);extern eXosip_t eXosip;static int dtls_socket;static struct sockaddr_storage ai_addr;static char dtls_firewall_ip[64];static char dtls_firewall_port[10];static SSL_CTX *server_ctx;static SSL_CTX *client_ctx;/* persistent connection */struct socket_tab{  char remote_ip[65];  int remote_port;  SSL *ssl_conn;  int ssl_state;  int ssl_type;};#ifndef EXOSIP_MAX_SOCKETS#define EXOSIP_MAX_SOCKETS#endifstatic struct socket_tab dtls_socket_tab[EXOSIP_MAX_SOCKETS];static intdtls_tl_init (void){  dtls_socket = 0;  server_ctx = NULL;  client_ctx = NULL;  memset (&ai_addr, 0, sizeof (struct sockaddr_storage));  memset (&dtls_socket_tab, 0, sizeof (struct socket_tab) * EXOSIP_MAX_SOCKETS);  memset (dtls_firewall_ip, 0, sizeof (dtls_firewall_ip));  memset (dtls_firewall_port, 0, sizeof (dtls_firewall_port));  return OSIP_SUCCESS;}int staticprint_ssl_error (int err){  switch (err)    {      case SSL_ERROR_NONE:        OSIP_TRACE (osip_trace                    (__FILE__, __LINE__, OSIP_ERROR, NULL,                     "SSL ERROR NONE - OK\n"));        break;      case SSL_ERROR_ZERO_RETURN:        OSIP_TRACE (osip_trace                    (__FILE__, __LINE__, OSIP_ERROR, NULL,                     "SSL ERROR ZERO RETURN - SHUTDOWN\n"));        break;      case SSL_ERROR_WANT_READ:        OSIP_TRACE (osip_trace                    (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL want read\n"));        break;      case SSL_ERROR_WANT_WRITE:        OSIP_TRACE (osip_trace                    (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL want write\n"));        break;      case SSL_ERROR_SSL:        OSIP_TRACE (osip_trace                    (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL ERROR\n"));        break;      case SSL_ERROR_SYSCALL:        OSIP_TRACE (osip_trace                    (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL ERROR SYSCALL\n"));        break;      default:        OSIP_TRACE (osip_trace                    (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL problem\n"));    }  return OSIP_SUCCESS;}static intshutdown_free_server_dtls (int pos){  int i, err;  if (dtls_socket_tab[pos].ssl_type == 1)    {      if (dtls_socket_tab[pos].ssl_conn != NULL)        {#ifdef SSLDEBUG          OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL,                                  "DTLS server SSL_shutdown\n"));#endif          i = SSL_shutdown (dtls_socket_tab[pos].ssl_conn);          if (i <= 0)            {              err = SSL_get_error (dtls_socket_tab[pos].ssl_conn, i);              print_ssl_error (err);#ifdef SSLDEBUG              OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,                                      "DTLS server shutdown <= 0\n"));#endif          } else            {#ifdef SSLDEBUG              OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL,                                      "DTLS server shutdown > 0\n"));#endif            }          SSL_free (dtls_socket_tab[pos].ssl_conn);#if 0          if (dtls_socket_tab[pos].ssl_ctx != NULL)            SSL_CTX_free (dtls_socket_tab[pos].ssl_ctx);#endif          memset (&(dtls_socket_tab[pos]), 0, sizeof (struct socket_tab));          return OSIP_SUCCESS;      } else        {          OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,                                  "DTLS server shutdown: invalid SSL object!\n"));          return -1;        }    }  return -1;}static intshutdown_free_client_dtls (int pos){  int i, err;  BIO *rbio;  struct addrinfo *addrinfo;  struct __eXosip_sockaddr addr;  if (dtls_socket_tab[pos].ssl_type == 2)    {      if (dtls_socket_tab[pos].ssl_conn != NULL)        {          i = eXosip_get_addrinfo (&addrinfo,                                   dtls_socket_tab[pos].remote_ip,                                   dtls_socket_tab[pos].remote_port, IPPROTO_UDP);          if (i != 0)            {              return -1;            }          memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);          eXosip_freeaddrinfo (addrinfo);          rbio = BIO_new_dgram (dtls_socket, BIO_NOCLOSE);          BIO_dgram_set_peer (rbio, &addr);          (dtls_socket_tab[pos].ssl_conn)->rbio = rbio;          i = SSL_shutdown (dtls_socket_tab[pos].ssl_conn);          if (i <= 0)            {              err = SSL_get_error (dtls_socket_tab[pos].ssl_conn, i);#ifdef SSLDEBUG              OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,                                      "DTLS client shutdown error %d <= 0\n", i));#endif              print_ssl_error (err);          } else            {#ifdef SSLDEBUG              OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL,                                      "DTLS client shutdown > 0\n"));#endif            }          SSL_free (dtls_socket_tab[pos].ssl_conn);#if 0          if (dtls_socket_tab[pos].ssl_ctx != NULL)            SSL_CTX_free (dtls_socket_tab[pos].ssl_ctx);#endif          memset (&(dtls_socket_tab[pos]), 0, sizeof (struct socket_tab));          return OSIP_SUCCESS;      } else        {          OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,                                  "DTLS client shutdown: invalid SSL object!\n"));          return -1;        }    }  return -1;}static intdtls_tl_free (void){  int pos;  if (server_ctx != NULL)    SSL_CTX_free (server_ctx);  if (client_ctx != NULL)    SSL_CTX_free (client_ctx);  for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++)    {      if (dtls_socket_tab[pos].ssl_conn != NULL)        {          shutdown_free_client_dtls (pos);          shutdown_free_server_dtls (pos);        }    }  memset (&dtls_socket_tab, 0, sizeof (struct socket_tab) * EXOSIP_MAX_SOCKETS);  memset (dtls_firewall_ip, 0, sizeof (dtls_firewall_ip));  memset (dtls_firewall_port, 0, sizeof (dtls_firewall_port));  memset (&ai_addr, 0, sizeof (struct sockaddr_storage));  if (dtls_socket > 0)    close (dtls_socket);  dtls_socket = 0;  return OSIP_SUCCESS;}static intdtls_tl_open (void){  int res;  struct addrinfo *addrinfo = NULL;  struct addrinfo *curinfo;  int sock = -1;  if (eXtl_dtls.proto_port < 0)    eXtl_dtls.proto_port = 5061;  server_ctx = initialize_server_ctx (SERVER_KEYFILE, SERVER_CERTFILE, PASSWORD,                                      IPPROTO_TCP);  client_ctx = initialize_client_ctx (CLIENT_KEYFILE, CLIENT_CERTFILE, PASSWORD,                                      IPPROTO_TCP);  res = eXosip_get_addrinfo (&addrinfo,                             eXtl_dtls.proto_ifs,                             eXtl_dtls.proto_port, eXtl_dtls.proto_num);  if (res)    return -1;  for (curinfo = addrinfo; curinfo; curinfo = curinfo->ai_next)    {      socklen_t len;      if (curinfo->ai_protocol && curinfo->ai_protocol != eXtl_dtls.proto_num)        {          OSIP_TRACE (osip_trace                      (__FILE__, __LINE__, OSIP_INFO3, NULL,                       "eXosip: Skipping protocol %d\n", curinfo->ai_protocol));          continue;        }      sock = (int) socket (curinfo->ai_family, curinfo->ai_socktype,                           curinfo->ai_protocol);      if (sock < 0)        {          OSIP_TRACE (osip_trace                      (__FILE__, __LINE__, OSIP_ERROR, NULL,                       "eXosip: Cannot create socket %s!\n", strerror (errno)));          continue;        }      if (curinfo->ai_family == AF_INET6)        {#ifdef IPV6_V6ONLY          if (setsockopt_ipv6only (sock))            {              close (sock);              sock = -1;              OSIP_TRACE (osip_trace                          (__FILE__, __LINE__, OSIP_ERROR, NULL,                           "eXosip: Cannot set socket option %s!\n",                           strerror (errno)));              continue;            }#endif /* IPV6_V6ONLY */        }      res = bind (sock, curinfo->ai_addr, curinfo->ai_addrlen);      if (res < 0)        {          OSIP_TRACE (osip_trace                      (__FILE__, __LINE__, OSIP_ERROR, NULL,                       "eXosip: Cannot bind socket node:%s family:%d %s\n",                       eXtl_dtls.proto_ifs, curinfo->ai_family, strerror (errno)));          close (sock);          sock = -1;          continue;        }

⌨️ 快捷键说明

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