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

📄 extl_dtls.c

📁 libeXosip2-3.0.3.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
		    {		      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 */	      SSL_set_options (dtls_socket_tab[pos].ssl_conn, SSL_OP_NO_QUERY_MTU);	      SSL_set_mtu (dtls_socket_tab[pos].ssl_conn, 2000);	      /* MTU query */	      /* BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); */	      SSL_set_options (dtls_socket_tab[pos].ssl_conn, SSL_OP_COOKIE_EXCHANGE);	      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));	      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 -1;	    }	  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 0;}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 0;}#ifndef INET6_ADDRSTRLEN#define INET6_ADDRSTRLEN 46#endifstatic intdtls_tl_send_message(osip_transaction_t * tr, osip_message_t * sip, char *host,                    int port, int out_socket){  int len = 0;  size_t length = 0;  struct addrinfo *addrinfo;  struct __eXosip_sockaddr addr;  char *message;  char ipbuf[INET6_ADDRSTRLEN];  int i;  int pos;  struct socket_tab *socket_tab_used=NULL;  BIO *sbio=NULL;  if (dtls_socket <= 0)    return -1;  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;  if (MSG_IS_REQUEST(sip))    {      if (MSG_IS_REGISTER(sip)	  ||MSG_IS_INVITE(sip)	  ||MSG_IS_SUBSCRIBE(sip)	  || MSG_IS_NOTIFY(sip))	eXtl_update_local_target(sip);    }  i=-1;#ifndef MINISIZE  if (tr!=NULL && tr->record.name[0]!='\0' && tr->record.srventry[0].srv[0]!='\0')    {      /* always choose the first here.	 if a network error occur, remove first entry and	 replace with next entries.      */      osip_srv_entry_t *srv;      int n=0;      for (srv = &tr->record.srventry[0];	   n<10 && tr->record.srventry[0].srv[0];	   srv = &tr->record.srventry[0])	{	  i = eXosip_get_addrinfo (&addrinfo, srv->srv, srv->port, IPPROTO_UDP);	  if (i == 0)	    {	      host = srv->srv;	      port = srv->port;	      break;	    }	  memmove(&tr->record.srventry[0], &tr->record.srventry[1], 9*sizeof(osip_srv_entry_t));	  memset(&tr->record.srventry[9], 0, sizeof(osip_srv_entry_t));	  i=-1;	  /* copy next element */	  n++;	}    }#endif    /* if SRV was used, distination may be already found */  if (i != 0)    {      i = eXosip_get_addrinfo (&addrinfo, host, port, IPPROTO_UDP);    }    if (i != 0)    {      return -1;    }    memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);  len = addrinfo->ai_addrlen;    eXosip_freeaddrinfo (addrinfo);    /* 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;    }    switch ( ((struct sockaddr *)&addr)->sa_family )    {    case AF_INET:      inet_ntop (((struct sockaddr *)&addr)->sa_family, &(((struct sockaddr_in *) &addr)->sin_addr),		 ipbuf, sizeof (ipbuf));      break;    case AF_INET6:      inet_ntop (((struct sockaddr *)&addr)->sa_family,		 &(((struct sockaddr_in6 *) &addr)->sin6_addr), ipbuf,		 sizeof (ipbuf));      break;    default:      strncpy (ipbuf, "(unknown)", sizeof (ipbuf));      break;    }    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,                          "Message sent: \n%s (to dest=%s:%i)\n",                          message, ipbuf, port));  for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++)    {      if (dtls_socket_tab[pos].ssl_conn != NULL	  && dtls_socket_tab[pos].ssl_type == EXOSIP_AS_A_SERVER)	{	  if (dtls_socket_tab[pos].remote_port == port &&	      (strcmp (dtls_socket_tab[pos].remote_ip, ipbuf) == 0))	    {	      BIO *rbio;	      socket_tab_used = &dtls_socket_tab[pos];	      rbio = BIO_new_dgram (dtls_socket, BIO_NOCLOSE);	      BIO_dgram_set_peer (rbio, &addr);	      dtls_socket_tab[pos].ssl_conn->rbio = rbio;	      break;	    }	}    }  if (socket_tab_used==NULL)    {      for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++)	{	  if (dtls_socket_tab[pos].ssl_conn != NULL	      && dtls_socket_tab[pos].ssl_type == EXOSIP_AS_A_CLIENT)	    {	      if (dtls_socket_tab[pos].remote_port == port &&		  (strcmp (dtls_socket_tab[pos].remote_ip, ipbuf) == 0))		{		  BIO *rbio;		  socket_tab_used = &dtls_socket_tab[pos];		  rbio = BIO_new_dgram (dtls_socket, BIO_NOCLOSE);		  BIO_dgram_set_peer (rbio, &addr);		  dtls_socket_tab[pos].ssl_conn->rbio = rbio;		  break;		}	    }	}    }  if (socket_tab_used==NULL)    {      /* 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)    {      /* create a new one */      SSL_CTX_set_read_ahead (client_ctx, 1);      dtls_socket_tab[pos].ssl_conn = SSL_new (client_ctx);      if (dtls_socket_tab[pos].ssl_conn == NULL)	{	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,				  "DTLS SSL_new error\n"));	  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));	  osip_free (message);	  return -1;	}      if (connect (dtls_socket, (struct sockaddr *) &addr, sizeof (addr)) == -1)	{	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,				  "DTLS connect error\n"));	  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));	  osip_free (message);	  return -1;	}            SSL_set_options (dtls_socket_tab[pos].ssl_conn, SSL_OP_NO_QUERY_MTU);      SSL_set_mtu (dtls_socket_tab[pos].ssl_conn, 2000);      SSL_set_connect_state (dtls_socket_tab[pos].ssl_conn);      sbio = BIO_new_dgram (dtls_socket, BIO_NOCLOSE);      BIO_ctrl_set_connected (sbio, 1, (struct sockaddr *) &addr);      SSL_set_bio (dtls_socket_tab[pos].ssl_conn, sbio, sbio);      dtls_socket_tab[pos].ssl_type = 2;      dtls_socket_tab[pos].ssl_state = 2;            osip_strncpy (dtls_socket_tab[pos].remote_ip, ipbuf,		    sizeof (dtls_socket_tab[pos].remote_ip));      dtls_socket_tab[pos].remote_port = port;    }  i = SSL_write (dtls_socket_tab[pos].ssl_conn, message, length);  if (i<0)    {      i = SSL_get_error (dtls_socket_tab[pos].ssl_conn, i);      print_ssl_error (i);      if (i==SSL_ERROR_SSL	  || i==SSL_ERROR_SYSCALL)	{	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,				  "DTLS SSL_write error\n"));	  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));	  	}#ifndef MINISIZE      /* delete first SRV entry that is not reachable */      if (tr->record.name[0]!='\0' && tr->record.srventry[0].srv[0]!='\0')	{	  memmove(&tr->record.srventry[0], &tr->record.srventry[1], 9*sizeof(osip_srv_entry_t));	  memset(&tr->record.srventry[9], 0, sizeof(osip_srv_entry_t));	  osip_free (message);	  return 0; /* retry for next retransmission! */	}#endif      /* SIP_NETWORK_ERROR; */      osip_free (message);      return -1;    }  if (eXosip.keep_alive > 0)    {      if (MSG_IS_REGISTER (sip))        {          eXosip_reg_t *reg = NULL;	            if (_eXosip_reg_find (&reg, tr) == 0)            {              memcpy (&(reg->addr), &addr, len);              reg->len = len;            }        }    }    osip_free (message);  return 0;}static intdtls_tl_keepalive(void){  char buf[4] = "jaK";  eXosip_reg_t *jr;  for (jr = eXosip.j_reg; jr != NULL; jr = jr->next)    {      if (jr->len > 0)        {          if (sendto (dtls_socket, (const void *) buf, 4, 0,                      (struct sockaddr *) &(jr->addr), jr->len) > 0)            {              OSIP_TRACE (osip_trace                          (__FILE__, __LINE__, OSIP_INFO1, NULL,                           "eXosip: Keep Alive sent on DTLS!\n"));            }        }    }  return 0;}static intdtls_tl_set_socket(int socket){  dtls_socket = socket;    return 0;}static intdtls_tl_masquerade_contact(const char *public_address, int port){  if (public_address == NULL || public_address[0] == '\0')    {      memset (dtls_firewall_ip, '\0', sizeof (dtls_firewall_ip));      return 0;    }  snprintf (dtls_firewall_ip, sizeof (dtls_firewall_ip), "%s", public_address);  if (port > 0)    {      snprintf (dtls_firewall_port, sizeof(dtls_firewall_port), "%i", port);    }  return 0;}static intdtls_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 (dtls_firewall_ip!='\0')    snprintf(ip, ip_size, "%s", dtls_firewall_ip);    if (dtls_firewall_port!='\0')    snprintf(port, port_size, "%s", dtls_firewall_port);  return 0;}struct eXtl_protocol eXtl_dtls =   {    1,    5061,    "UDP-DTLS",    "0.0.0.0",    IPPROTO_UDP,    AF_INET,    0,    0,        &dtls_tl_init,    &dtls_tl_free,    &dtls_tl_open,    &dtls_tl_set_fdset,    &dtls_tl_read_message,    &dtls_tl_send_message,    &dtls_tl_keepalive,    &dtls_tl_set_socket,    &dtls_tl_masquerade_contact,    &dtls_tl_get_masquerade_contact};#endif

⌨️ 快捷键说明

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