📄 extl_dtls.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 "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 + -