📄 extl_tls.c
字号:
} if (pos == EXOSIP_MAX_SOCKETS) return -1; res = eXosip_get_addrinfo (&addrinfo, host, port, IPPROTO_TCP); if (res) return -1; for (curinfo = addrinfo; curinfo; curinfo = curinfo->ai_next) { if (curinfo->ai_protocol && curinfo->ai_protocol != IPPROTO_TCP) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Skipping protocol %d\n", curinfo->ai_protocol)); continue; } res = getnameinfo ((struct sockaddr *) curinfo->ai_addr, curinfo->ai_addrlen, src6host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (res == 0) { int i = _tls_tl_find_socket (src6host, port); if (i >= 0) { eXosip_freeaddrinfo (addrinfo); return i; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "New binding with %s\n", src6host)); } sock = (int) socket (curinfo->ai_family, curinfo->ai_socktype, curinfo->ai_protocol); if (sock < 0) {#if !defined(OSIP_MT) || defined(_WIN32_WCE) OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot create socket!\n"));#else OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot create socket %s!\n", strerror (errno)));#endif continue; } if (curinfo->ai_family == AF_INET6) {#ifdef IPV6_V6ONLY if (setsockopt_ipv6only (sock)) { close (sock); sock = -1;#if !defined(OSIP_MT) || defined(_WIN32_WCE) OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot set socket option!\n"));#else OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot set socket option %s!\n", strerror (errno)));#endif continue; }#endif /* IPV6_V6ONLY */ } res = connect (sock, curinfo->ai_addr, curinfo->ai_addrlen); if (res < 0) {#if !defined(OSIP_MT) || defined(_WIN32_WCE) OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot bind socket node:%s family:%d\n", host, curinfo->ai_family));#else OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot bind socket node:%s family:%d %s\n", host, curinfo->ai_family, strerror (errno)));#endif close (sock); sock = -1; continue; } break; } eXosip_freeaddrinfo (addrinfo); if (sock > 0) { ctx = initialize_client_ctx (eXosip_tls_ctx_params.client.priv_key, eXosip_tls_ctx_params.client.cert, eXosip_tls_ctx_params.server.priv_key_pw, IPPROTO_TCP); //FIXME: changed parameter from ctx to client_ctx -> works now ssl = SSL_new (ctx); if (ssl == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL_new error\n")); close (sock); if (ctx != NULL) SSL_CTX_free (ctx); return -1; } sbio = BIO_new_socket (sock, BIO_NOCLOSE); if (sbio == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "BIO_new_socket error\n")); SSL_shutdown (ssl); close (sock); SSL_free (ssl); if (ctx != NULL) SSL_CTX_free (ctx); return -1; } SSL_set_bio (ssl, sbio, sbio); res = SSL_connect (ssl); if (res < 1) { res = SSL_get_error (ssl, res); print_ssl_error (res); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL_connect error\n")); SSL_shutdown (ssl); close (sock); SSL_free (ssl); if (ctx != NULL) SSL_CTX_free (ctx); return -1; } cert = SSL_get_peer_certificate (ssl); if (cert != 0) { int cert_err; tls_dump_cert_info ("tls_connect: remote certificate: ", cert); cert_err = SSL_get_verify_result (ssl); if (cert_err != X509_V_OK) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Failed to verify remote certificate\n")); tls_dump_verification_failure (cert_err); if (eXosip_tls_ctx_params.server.cert[0] != '\0') { X509_free(cert); return -1; } else if (cert_err != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && cert_err != X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN && cert_err != X509_V_ERR_CRL_HAS_EXPIRED && cert_err != X509_V_ERR_CERT_HAS_EXPIRED && cert_err != X509_V_ERR_CERT_REVOKED && cert_err != X509_V_ERR_CERT_UNTRUSTED && cert_err != X509_V_ERR_CERT_REJECTED) { X509_free (cert); return -1; } /*else -> I want to keep going ONLY when API didn't specified any SSL server certificate */ } X509_free (cert); } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "No certificate received\n")); //X509_free is not necessary because no cert-object was created -> cert == NULL return -1; } tls_socket_tab[pos].socket = sock; if (src6host[0] == '\0') osip_strncpy (tls_socket_tab[pos].remote_ip, host, sizeof (tls_socket_tab[pos].remote_ip) - 1); else osip_strncpy (tls_socket_tab[pos].remote_ip, src6host, sizeof (tls_socket_tab[pos].remote_ip) - 1); tls_socket_tab[pos].remote_port = port; tls_socket_tab[pos].ssl_conn = ssl; tls_socket_tab[pos].ssl_state = 3; return pos; } return -1;}static inttls_tl_send_message (osip_transaction_t * tr, osip_message_t * sip, char *host, int port, int out_socket){ size_t length = 0; char *message; int i; SSL *ssl = NULL; if (host == NULL) { host = sip->req_uri->host; if (sip->req_uri->port != NULL) port = osip_atoi (sip->req_uri->port); else port = 5061; } if (port == 5060) port = 5061; /* remove preloaded route if there is no tag in the To header */ { osip_route_t *route = NULL; osip_generic_param_t *tag = NULL; osip_message_get_route (sip, 0, &route); osip_to_get_tag (sip->to, &tag); if (tag == NULL && route != NULL && route->url != NULL) { osip_list_remove (&sip->routes, 0); } i = osip_message_to_str (sip, &message, &length); if (tag == NULL && route != NULL && route->url != NULL) { osip_list_add (&sip->routes, route, 0); } } if (i != 0 || length <= 0) { return -1; } if (out_socket > 0) { int pos; for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++) { if (tls_socket_tab[pos].socket != 0) { if (tls_socket_tab[pos].socket == out_socket) { out_socket = tls_socket_tab[pos].socket; ssl = tls_socket_tab[pos].ssl_conn; OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message sent: \n%s (reusing REQUEST connection)\n", message)); break; } } } if (pos == EXOSIP_MAX_SOCKETS) out_socket = 0; } /* Step 1: find existing socket to send message */ if (out_socket <= 0) { int pos = _tls_tl_find_socket (host, port); /* Step 2: create new socket with host:port */ if (pos < 0) { pos = _tls_tl_connect_socket (host, port); } if (pos >= 0) { out_socket = tls_socket_tab[pos].socket; ssl = tls_socket_tab[pos].ssl_conn; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message sent: \n%s (to dest=%s:%i)\n", message, host, port)); } if (out_socket <= 0 || ssl == NULL) { return -1; } SSL_set_mode (ssl, SSL_MODE_AUTO_RETRY); while (1) { i = SSL_write (ssl, (const void *) message, length); if (i <= 0) { i = SSL_get_error (ssl, i); print_ssl_error (i); if (i == SSL_ERROR_WANT_READ) continue; osip_free (message); return -1; } break; } osip_free (message); return OSIP_SUCCESS;}static inttls_tl_keepalive (void){ return OSIP_SUCCESS;}static inttls_tl_set_socket (int socket){ tls_socket = socket; return OSIP_SUCCESS;}static inttls_tl_masquerade_contact (const char *public_address, int port){ if (public_address == NULL || public_address[0] == '\0') { memset (tls_firewall_ip, '\0', sizeof (tls_firewall_ip)); return OSIP_SUCCESS; } snprintf (tls_firewall_ip, sizeof (tls_firewall_ip), "%s", public_address); if (port > 0) { snprintf (tls_firewall_port, sizeof (tls_firewall_port), "%i", port); } return OSIP_SUCCESS;}static inttls_tl_get_masquerade_contact (char *ip, int ip_size, char *port, int port_size){ memset (ip, 0, ip_size); memset (port, 0, port_size); if (tls_firewall_ip[0] != '\0') snprintf (ip, ip_size, "%s", tls_firewall_ip); if (tls_firewall_port[0] != '\0') snprintf (port, port_size, "%s", tls_firewall_port); return OSIP_SUCCESS;}struct eXtl_protocol eXtl_tls = { 1, 5061, "TLS", "0.0.0.0", IPPROTO_TCP, AF_INET, 0, 0, &tls_tl_init, &tls_tl_free, &tls_tl_open, &tls_tl_set_fdset, &tls_tl_read_message, &tls_tl_send_message, &tls_tl_keepalive, &tls_tl_set_socket, &tls_tl_masquerade_contact, &tls_tl_get_masquerade_contact};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -