Exemplo n.º 1
0
/**
 * Task to receive incoming packets for STUN processing.
 */
static void
stun_read_task (void *cls)
{
  ssize_t size;
  
  rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
					 ls,
					 &stun_read_task,
					 NULL);
  size = GNUNET_NETWORK_socket_recvfrom_amount (ls);
  if (size > 0)
  {
    GNUNET_break (0);
    GNUNET_SCHEDULER_shutdown ();
    global_ret = 1;
    return;
  }
  {
    char buf[size + 1];
    struct sockaddr_storage sa;
    socklen_t salen = sizeof (sa);
    ssize_t ret;
    
    ret = GNUNET_NETWORK_socket_recvfrom (ls,
					  buf,
					  size + 1,
					  (struct sockaddr *) &sa,
					  &salen);
    if (ret != size)
    {
      GNUNET_break (0);
      GNUNET_SCHEDULER_shutdown ();
      global_ret = 1;
      return;
    }
    (void) GNUNET_NAT_stun_handle_packet (nh,
					  (const struct sockaddr *) &sa,
					  salen,
					  buf,
					  ret);
  }
}
Exemplo n.º 2
0
/**
 * Actually do the reading of a DNS packet from our UDP socket and see
 * if we have a valid, matching, pending request.
 *
 * @param rs request socket with callback details
 * @param dnsout socket to read from
 * @return GNUNET_OK on success, GNUNET_NO on drop, GNUNET_SYSERR on IO-errors (closed socket)
 */
static int
do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs,
	     struct GNUNET_NETWORK_Handle *dnsout)
{
  struct sockaddr_storage addr;
  socklen_t addrlen;
  struct GNUNET_TUN_DnsHeader *dns;
  ssize_t r;
  int len;

#ifndef MINGW
  if (0 != ioctl (GNUNET_NETWORK_get_fd (dnsout), FIONREAD, &len))
  {
    /* conservative choice: */
    len = UINT16_MAX;
  }
#else
  /* port the code above? */
  len = UINT16_MAX;
#endif
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Receiving %d byte DNS reply\n",
	      len); 
  {
    unsigned char buf[len] GNUNET_ALIGN;

    addrlen = sizeof (addr);
    memset (&addr, 0, sizeof (addr));  
    r = GNUNET_NETWORK_socket_recvfrom (dnsout, 
					buf, sizeof (buf),
					(struct sockaddr*) &addr, &addrlen);
    if (-1 == r)
    {
      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "recvfrom");
      GNUNET_NETWORK_socket_close (dnsout);
      return GNUNET_SYSERR;
    }
    if (sizeof (struct GNUNET_TUN_DnsHeader) > r)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
		  _("Received DNS response that is too small (%u bytes)"),
		  r);
      return GNUNET_NO;
    }
    dns = (struct GNUNET_TUN_DnsHeader *) buf;
    if ( (addrlen != rs->addrlen) ||
	 (0 != memcmp (&rs->addr,
		       &addr,
		       addrlen)) ||	 
       (0 == GNUNET_TIME_absolute_get_remaining (rs->timeout).rel_value) )
    {
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
		  "Request timeout or invalid sender address; ignoring reply\n"); 
      return GNUNET_NO;
    }
    if (NULL != rs->rc)
      rs->rc (rs->rc_cls,
	      rs,
	      dns,
	      r);
  }  
  return GNUNET_OK;
}