Exemple #1
0
static int
udp_tl_read_message (fd_set * osip_fdset)
{
  char *buf;
  int i;

  if (udp_socket <= 0)
    return -1;

  if (FD_ISSET (udp_socket, osip_fdset))
    {
      struct sockaddr_storage sa;

#ifdef __linux
      socklen_t slen;
#else
      int slen;
#endif
      if (eXtl_udp.proto_family == AF_INET)
        slen = sizeof (struct sockaddr_in);
      else
        slen = sizeof (struct sockaddr_in6);

      buf = (char *) osip_malloc (SIP_MESSAGE_MAX_LENGTH * sizeof (char) + 1);
      if (buf == NULL)
        return OSIP_NOMEM;

      i = recvfrom (udp_socket, buf,
                    SIP_MESSAGE_MAX_LENGTH, 0, (struct sockaddr *) &sa, &slen);

#ifdef ENABLE_MYCRYPT
	  CRYPT_DATA_SIP((unsigned char *)buf, i);
#endif // ENABLE_MYCRYPT
	  //SIP解密点
      if (i > 5)
        {
          char src6host[NI_MAXHOST];
          int recvport = 0;
          int err;

          osip_strncpy (buf + i, "\0", 1);
          OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,
                                  "Received message: \n%s\n", buf));

          memset (src6host, 0, sizeof (src6host));

          if (eXtl_udp.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));

          _eXosip_handle_incoming_message (buf, i, udp_socket, src6host, recvport);

        }
#ifndef MINISIZE
      else if (i < 0)
        {
          OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
                                  "Could not read socket\n"));
      } else
        {
          OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,
                                  "Dummy SIP message received\n"));
        }
#endif

      osip_free (buf);
    }

  return OSIP_SUCCESS;
}
Exemple #2
0
static int
tcp_tl_read_message(fd_set *osip_fdset)
{
  int pos = 0;
  char *buf;

  if (FD_ISSET (tcp_socket, osip_fdset))
    {
      /* accept incoming connection */
      char src6host[NI_MAXHOST];
      int recvport = 0;
      struct sockaddr_storage sa;
      int sock;
      int i;

#ifdef __linux
      socklen_t slen;
#else
      int slen;
#endif
      if (eXtl_tcp.proto_family == AF_INET)
	slen = sizeof (struct sockaddr_in);
      else
	slen = sizeof (struct sockaddr_in6);

      for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++)
	{
	  if (tcp_socket_tab[pos].socket == 0)
	    break;
	}
      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL,
			      "creating TCP socket at index: %i\n", pos));
      sock = accept (tcp_socket,
		     (struct sockaddr *) &sa, &slen);
      if (sock < 0)
	{
	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
				  "Error accepting TCP socket\n"));
	}
      else
	{
	  tcp_socket_tab[pos].socket = sock;
	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,
				  "New TCP connection accepted\n"));
	  
	  memset (src6host, 0, sizeof (src6host));
	  
	  if (eXtl_tcp.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));
		osip_strncpy (tcp_socket_tab[pos].remote_ip, src6host,
			      sizeof (tcp_socket_tab[pos].remote_ip)-1);
		tcp_socket_tab[pos].remote_port = recvport;
	      }
	  }
#else
	  i = getnameinfo ((struct sockaddr *) &sa, slen,
			   src6host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
	  
	  if (i != 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));
	      osip_strncpy (tcp_socket_tab[pos].remote_ip, src6host,
			    sizeof (tcp_socket_tab[pos].remote_ip)-1);
	      tcp_socket_tab[pos].remote_port = recvport;
	    }
#endif
	} 
    }



  buf=NULL;

  for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++)
    {
      if (tcp_socket_tab[pos].socket > 0
	  && FD_ISSET (tcp_socket_tab[pos].socket, osip_fdset))
	{
	  int i;

	  if (buf==NULL)
	    buf = (char *) osip_malloc (SIP_MESSAGE_MAX_LENGTH * sizeof (char) + 1);
	  if (buf==NULL)
	    return -1;

	  i = recv (tcp_socket_tab[pos].socket, buf, SIP_MESSAGE_MAX_LENGTH, 0);
	  if (i > 5)
	    {
	      osip_strncpy (buf + i, "\0", 1);
	      OSIP_TRACE (osip_trace
			  (__FILE__, __LINE__, OSIP_INFO1, NULL,
			   "Received TCP message: \n%s\n", buf));
	      _eXosip_handle_incoming_message (buf, i,
					       tcp_socket_tab[pos].socket,
					       tcp_socket_tab[pos].remote_ip,
					       tcp_socket_tab[pos].remote_port);
	    }
	  else if (i < 0)
	    {
	      OSIP_TRACE (osip_trace
			  (__FILE__, __LINE__, OSIP_ERROR, NULL,
			   "Could not read socket - close it\n"));
	      close (tcp_socket_tab[pos].socket);
	      memset (&(tcp_socket_tab[pos]), 0, sizeof (tcp_socket_tab[pos]));
	    }
	  else if (i == 0)
	    {
	      OSIP_TRACE (osip_trace
			  (__FILE__, __LINE__, OSIP_INFO1, NULL,
			   "End of stream (read 0 byte from %s:%i)\n",
			   tcp_socket_tab[pos].remote_ip,
			   tcp_socket_tab[pos].remote_port));
	      close (tcp_socket_tab[pos].socket);
	      memset (&(tcp_socket_tab[pos]), 0, sizeof (tcp_socket_tab[pos]));
	    }
#ifndef MINISIZE
	  else
	    {
	      /* we expect at least one byte, otherwise there's no doubt that it is not a sip message ! */
	      OSIP_TRACE (osip_trace
			  (__FILE__, __LINE__, OSIP_INFO1, NULL,
			   "Dummy SIP message received (size=%i)\n", i));
	    }
#endif
	}
    }

  if (buf!=NULL)
    osip_free (buf);

  return 0;
}
static int
dtls_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 -1;

      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 */
	      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;
}