📄 extl_dtls.c
字号:
len = sizeof (ai_addr); res = getsockname (sock, (struct sockaddr *) &ai_addr, &len); if (res != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: Cannot get socket name (%s)\n", strerror (errno))); memcpy (&ai_addr, curinfo->ai_addr, curinfo->ai_addrlen); } if (eXtl_dtls.proto_num == IPPROTO_TCP) { res = listen (sock, SOMAXCONN); 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; } } break; } eXosip_freeaddrinfo (addrinfo); if (sock < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: Cannot bind on port: %i\n", eXtl_dtls.proto_port)); return -1; } dtls_socket = sock; if (eXtl_dtls.proto_port == 0) { /* get port number from socket */ if (eXtl_dtls.proto_family == AF_INET) eXtl_dtls.proto_port = ntohs (((struct sockaddr_in *) &ai_addr)->sin_port); else eXtl_dtls.proto_port = ntohs (((struct sockaddr_in6 *) &ai_addr)->sin6_port); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "eXosip: Binding on port %i!\n", eXtl_dtls.proto_port)); } snprintf (dtls_firewall_port, sizeof (dtls_firewall_port), "%i", eXtl_dtls.proto_port); return OSIP_SUCCESS;}#define EXOSIP_AS_A_SERVER 1#define EXOSIP_AS_A_CLIENT 2static intdtls_tl_set_fdset (fd_set * osip_fdset, int *fd_max){ if (dtls_socket <= 0) return -1; eXFD_SET (dtls_socket, osip_fdset); if (dtls_socket > *fd_max) *fd_max = dtls_socket; return OSIP_SUCCESS;}static intdtls_tl_read_message (fd_set * osip_fdset){ char *enc_buf; char *dec_buf; int i; int enc_buf_len; if (dtls_socket <= 0) return -1; if (FD_ISSET (dtls_socket, osip_fdset)) { struct sockaddr_storage sa;#ifdef __linux socklen_t slen;#else int slen;#endif if (eXtl_dtls.proto_family == AF_INET) slen = sizeof (struct sockaddr_in); else slen = sizeof (struct sockaddr_in6); enc_buf = (char *) osip_malloc (SIP_MESSAGE_MAX_LENGTH * sizeof (char) + 1); if (enc_buf == NULL) return OSIP_NOMEM; enc_buf_len = recvfrom (dtls_socket, enc_buf, SIP_MESSAGE_MAX_LENGTH, 0, (struct sockaddr *) &sa, &slen); if (enc_buf_len > 5) { char src6host[NI_MAXHOST]; int recvport = 0; int err; BIO *rbio; struct socket_tab *socket_tab_used = NULL; int pos; osip_strncpy (enc_buf + enc_buf_len, "\0", 1); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Received message: \n%s\n", enc_buf)); memset (src6host, 0, sizeof (src6host)); if (eXtl_dtls.proto_family == AF_INET) recvport = ntohs (((struct sockaddr_in *) &sa)->sin_port); else recvport = ntohs (((struct sockaddr_in6 *) &sa)->sin6_port);#if defined(__arc__) { struct sockaddr_in *fromsa = (struct sockaddr_in *) &sa; char *tmp; tmp = inet_ntoa (fromsa->sin_addr); if (tmp == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Message received from: NULL:%i inet_ntoa failure\n", recvport)); } else { snprintf (src6host, sizeof (src6host), "%s", tmp); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message received from: %s:%i\n", src6host, recvport)); } }#else err = getnameinfo ((struct sockaddr *) &sa, slen, src6host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (err != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Message received from: NULL:%i getnameinfo failure\n", recvport)); snprintf (src6host, sizeof (src6host), "127.0.0.1"); } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message received from: %s:%i\n", src6host, recvport)); }#endif OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message received from: %s:%i\n", src6host, recvport)); for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++) { if (dtls_socket_tab[pos].ssl_conn != NULL) { if (dtls_socket_tab[pos].remote_port == recvport && (strcmp (dtls_socket_tab[pos].remote_ip, src6host) == 0)) { socket_tab_used = &dtls_socket_tab[pos]; break; } } } if (socket_tab_used == NULL) { for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++) { if (dtls_socket_tab[pos].ssl_conn == NULL) { /* should accept this connection? */ break; } } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL, "creating DTLS socket at index: %i\n", pos)); if (pos < 0) { /* delete an old one! */ pos = 0; if (dtls_socket_tab[pos].ssl_conn != NULL) { shutdown_free_client_dtls (pos); shutdown_free_server_dtls (pos); } memset (&dtls_socket_tab[pos], 0, sizeof (struct socket_tab)); } } if (dtls_socket_tab[pos].ssl_conn == NULL) { BIO *wbio; if (!SSL_CTX_check_private_key (server_ctx)) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL CTX private key check error\n")); osip_free (enc_buf); return -1; } /* behave as a server: */ dtls_socket_tab[pos].ssl_conn = SSL_new (server_ctx); if (dtls_socket_tab[pos].ssl_conn == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL_new error\n")); osip_free (enc_buf); return -1; } /* No MTU query */#ifdef SSL_OP_NO_QUERY_MTU SSL_set_options (dtls_socket_tab[pos].ssl_conn, SSL_OP_NO_QUERY_MTU); SSL_set_mtu (dtls_socket_tab[pos].ssl_conn, 2000);#endif /* MTU query */ /* BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); */#ifdef SSL_OP_COOKIE_EXCHANGE SSL_set_options (dtls_socket_tab[pos].ssl_conn, SSL_OP_COOKIE_EXCHANGE);#endif wbio = BIO_new_dgram (dtls_socket, BIO_NOCLOSE); BIO_dgram_set_peer (wbio, &sa); SSL_set_bio (dtls_socket_tab[pos].ssl_conn, NULL, wbio); SSL_set_accept_state (dtls_socket_tab[pos].ssl_conn); dtls_socket_tab[pos].ssl_state = 0; dtls_socket_tab[pos].ssl_type = EXOSIP_AS_A_SERVER; osip_strncpy (dtls_socket_tab[pos].remote_ip, src6host, sizeof (dtls_socket_tab[pos].remote_ip) - 1); dtls_socket_tab[pos].remote_port = recvport; OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "New DTLS connection accepted\n")); } dec_buf = (char *) osip_malloc (SIP_MESSAGE_MAX_LENGTH * sizeof (char) + 1); if (dec_buf == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Allocation error\n")); osip_free (enc_buf); return OSIP_NOMEM; } rbio = BIO_new_mem_buf (enc_buf, enc_buf_len); BIO_set_mem_eof_return (rbio, -1); dtls_socket_tab[pos].ssl_conn->rbio = rbio; i = SSL_read (dtls_socket_tab[pos].ssl_conn, dec_buf, SIP_MESSAGE_MAX_LENGTH); /* done with the rbio */ BIO_free (dtls_socket_tab[pos].ssl_conn->rbio); dtls_socket_tab[pos].ssl_conn->rbio = BIO_new (BIO_s_mem ()); if (i > 5) { osip_strncpy (dec_buf + i, "\0", 1); _eXosip_handle_incoming_message (dec_buf, i, dtls_socket, src6host, recvport); }#ifndef MINISIZE else if (i <= 0) { err = SSL_get_error (dtls_socket_tab[pos].ssl_conn, i); print_ssl_error (err); if (err == SSL_ERROR_SYSCALL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "DTLS SYSCALL on SSL_read\n")); } else if (err == SSL_ERROR_SSL || err == SSL_ERROR_ZERO_RETURN) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "DTLS closed\n")); shutdown_free_client_dtls (pos); shutdown_free_server_dtls (pos); memset (&(dtls_socket_tab[pos]), 0, sizeof (dtls_socket_tab[pos])); } } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Dummy SIP message received\n")); }#endif osip_free (dec_buf); osip_free (enc_buf); } } return OSIP_SUCCESS;}static inteXtl_update_local_target (osip_message_t * req){ int pos = 0; if (dtls_firewall_ip != '\0') { while (!osip_list_eol (&req->contacts, pos)) { osip_contact_t *co; co = (osip_contact_t *) osip_list_get (&req->contacts, pos); pos++; if (co != NULL && co->url != NULL && co->url->host != NULL && 0 == osip_strcasecmp (co->url->host, dtls_firewall_ip)) { if (co->url->port == NULL && 0 != osip_strcasecmp (dtls_firewall_port, "5061")) { co->url->port = osip_strdup (dtls_firewall_port); } else if (co->url->port != NULL && 0 != osip_strcasecmp (dtls_firewall_port, co->url->port)) { osip_free (co->url->port); co->url->port = osip_strdup (dtls_firewall_port); } } } } return OSIP_SUCCESS;}#ifndef INET6_ADDRSTRLEN#define INET6_ADDRSTRLEN 46#endifstatic intdtls_tl_send_message (osip_transaction_t * tr, osip_message_t * sip, char *host,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -