*/
struct GNUNET_DNSSTUB_RequestSocket
{
-
+
/**
* UDP socket we use for this request for IPv4
*/
};
+/**
+ * Handle to the stub resolver.
+ */
struct GNUNET_DNSSTUB_Context
{
/**
- * Array of all open sockets for DNS requests.
+ * Array of all open sockets for DNS requests.
*/
struct GNUNET_DNSSTUB_RequestSocket sockets[DNS_SOCKET_MAX];
*
* @param af AF_INET or AF_INET6
* @return GNUNET_OK on success
- */
+ */
static struct GNUNET_NETWORK_Handle *
open_socket (int af)
{
}
sa->sa_family = af;
if (GNUNET_OK != GNUNET_NETWORK_socket_bind (ret,
- sa,
+ sa,
alen))
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Could not bind to any port: %s\n"),
STRERROR (errno));
GNUNET_NETWORK_socket_close (ret);
/**
* Get a socket of the specified address family to send out a
- * UDP DNS request to the Internet.
+ * UDP DNS request to the Internet.
*
+ * @param ctx the DNSSTUB context
* @param af desired address family
* @return NULL on error (given AF not "supported")
*/
struct GNUNET_DNSSTUB_RequestSocket *rs;
struct GNUNET_NETWORK_FDSet *rset;
- rs = &ctx->sockets[GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
+ rs = &ctx->sockets[GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
DNS_SOCKET_MAX)];
rs->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT);
switch (af)
break;
default:
return NULL;
- }
+ }
if (GNUNET_SCHEDULER_NO_TASK != rs->read_task)
{
GNUNET_SCHEDULER_cancel (rs->read_task);
* Perform DNS resolution.
*
* @param ctx stub resolver to use
- * @param af address family to use
+ * @param sa the socket address
+ * @param sa_len the socket length
* @param request DNS request to transmit
* @param request_len number of bytes in msg
* @param rc function to call with result
else
ret = rs->dnsout6;
GNUNET_assert (NULL != ret);
+ memcpy (&rs->addr,
+ sa,
+ sa_len);
+ rs->addrlen = sa_len;
rs->rc = rc;
rs->rc_cls = rc_cls;
- GNUNET_NETWORK_socket_sendto (ret,
- request,
- request_len,
- sa,
- sa_len);
+ if (GNUNET_SYSERR ==
+ GNUNET_NETWORK_socket_sendto (ret,
+ request,
+ request_len,
+ sa,
+ sa_len))
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Failed to send DNS request to %s\n"),
+ GNUNET_a2s (sa, sa_len));
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ _("Sent DNS request to %s\n"),
+ GNUNET_a2s (sa, sa_len));
return rs;
}
int af;
struct sockaddr_in v4;
struct sockaddr_in6 v6;
- struct sockaddr *so;
+ struct sockaddr *sa;
socklen_t salen;
struct GNUNET_NETWORK_Handle *dnsout;
struct GNUNET_DNSSTUB_RequestSocket *rs;
#if HAVE_SOCKADDR_IN_SIN_LEN
v4.sin_len = (u_char) salen;
#endif
- so = (struct sockaddr *) &v4;
+ sa = (struct sockaddr *) &v4;
af = AF_INET;
}
else if (1 == inet_pton (AF_INET6, ctx->dns_exit, &v6.sin6_addr))
#if HAVE_SOCKADDR_IN_SIN_LEN
v6.sin6_len = (u_char) salen;
#endif
- so = (struct sockaddr *) &v6;
+ sa = (struct sockaddr *) &v6;
af = AF_INET6;
- }
+ }
else
{
GNUNET_break (0);
return NULL;
}
memcpy (&rs->addr,
- so,
+ sa,
salen);
rs->addrlen = salen;
rs->rc = rc;
rs->rc_cls = rc_cls;
- GNUNET_NETWORK_socket_sendto (dnsout,
- request,
- request_len, so, salen);
+ if (GNUNET_SYSERR ==
+ GNUNET_NETWORK_socket_sendto (dnsout,
+ request,
+ request_len, sa, salen))
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Failed to send DNS request to %s\n"),
+ GNUNET_a2s (sa, salen));
rs->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT);
-
+
return rs;
}
/* 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,
+ memset (&addr, 0, sizeof (addr));
+ r = GNUNET_NETWORK_socket_recvfrom (dnsout,
buf, sizeof (buf),
(struct sockaddr*) &addr, &addrlen);
if (-1 == r)
}
if (sizeof (struct GNUNET_TUN_DnsHeader) > r)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Received DNS response that is too small (%u bytes)"),
r);
return GNUNET_NO;
if ( (addrlen != rs->addrlen) ||
(0 != memcmp (&rs->addr,
&addr,
- addrlen)) ||
- (0 == GNUNET_TIME_absolute_get_remaining (rs->timeout).rel_value) )
+ addrlen)) ||
+ (0 == GNUNET_TIME_absolute_get_remaining (rs->timeout).rel_value_us) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Request timeout or invalid sender address; ignoring reply\n");
return GNUNET_NO;
- rs->rc (rs->rc_cls,
- rs,
- dns,
- r);
- }
+ }
+ if (NULL != rs->rc)
+ rs->rc (rs->rc_cls,
+ rs,
+ dns,
+ r);
+ }
return GNUNET_OK;
}
}
+/**
+ * Cancel DNS resolution.
+ *
+ * @param rs resolution to cancel
+ */
+void
+GNUNET_DNSSTUB_resolve_cancel (struct GNUNET_DNSSTUB_RequestSocket *rs)
+{
+ rs->rc = NULL;
+}
+
/**
* Start a DNS stub resolver.
GNUNET_DNSSTUB_start (const char *dns_ip)
{
struct GNUNET_DNSSTUB_Context *ctx;
-
- ctx = GNUNET_malloc (sizeof (struct GNUNET_DNSSTUB_Context));
+
+ ctx = GNUNET_new (struct GNUNET_DNSSTUB_Context);
if (NULL != dns_ip)
ctx->dns_exit = GNUNET_strdup (dns_ip);
return ctx;
{
unsigned int i;
- for (i=0;i<=UINT16_MAX;i++)
+ for (i=0;i<DNS_SOCKET_MAX;i++)
cleanup_rs (&ctx->sockets[i]);
if (NULL != ctx->dns_exit)
{