WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
endif
-if HAVE_MHD
+if MINGW
GN_LIBMHD = -lmicrohttpd
HTTP_PLUGIN_LA = libgnunet_plugin_transport_http.la
HTTP_PLUGIN_CHECK = test_plugin_transport_http
/* peer wants to confirm that this is one of our addresses */
addr += slen;
alen -= slen;
+ if (GNUNET_OK !=
+ plugin->api->check_address (plugin->api->cls,
+ addr,
+ alen))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ _("Not confirming PING with address `%s' since I cannot confirm having this address.\n"),
+ a2s (plugin->short_name,
+ addr,
+ alen));
+ return GNUNET_NO;
+ }
oal = plugin->addresses;
while (NULL != oal)
{
break;
oal = oal->next;
}
- if (oal == NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Not confirming PING with address `%s' since I cannot confirm having this address.\n"),
- a2s (plugin->short_name,
- addr,
- alen));
- return GNUNET_NO;
- }
pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + alen + slen);
pong->header.size = htons (sizeof (struct TransportPongMessage) + alen + slen);
pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
&my_identity,
sizeof(struct GNUNET_PeerIdentity));
memcpy (&pong[1], plugin->short_name, slen);
- memcpy (&((char*)&pong[1])[slen], &oal[1], alen);
- if (GNUNET_TIME_absolute_get_remaining (oal->pong_sig_expires).value < PONG_SIGNATURE_LIFETIME.value / 4)
+ memcpy (&((char*)&pong[1])[slen], addr, alen);
+ if ( (oal != NULL) &&
+ (GNUNET_TIME_absolute_get_remaining (oal->pong_sig_expires).value < PONG_SIGNATURE_LIFETIME.value / 4) )
{
/* create / update cached sig */
#if DEBUG_TRANSPORT
GNUNET_assert (GNUNET_OK ==
GNUNET_CRYPTO_rsa_sign (my_private_key,
&pong->purpose,
- &oal->pong_signature));
+ &oal->pong_signature));
+ memcpy (&pong->signature,
+ &oal->pong_signature,
+ sizeof (struct GNUNET_CRYPTO_RsaSignature));
+ }
+ else if (oal == NULL)
+ {
+ /* not using cache (typically DV-only) */
+ pong->expiration = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME));
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CRYPTO_rsa_sign (my_private_key,
+ &pong->purpose,
+ &pong->signature));
}
else
{
+ /* can used cached version */
pong->expiration = GNUNET_TIME_absolute_hton (oal->pong_sig_expires);
+ memcpy (&pong->signature,
+ &oal->pong_signature,
+ sizeof (struct GNUNET_CRYPTO_RsaSignature));
}
- memcpy (&pong->signature,
- &oal->pong_signature,
- sizeof (struct GNUNET_CRYPTO_RsaSignature));
}
n = find_neighbour(peer);
GNUNET_assert (n != NULL);
* plugin. Check that this could be a valid address. This function
* is not expected to 'validate' the address in the sense of trying to
* connect to it but simply to see if the binary format is technically
- * legal for establishing a connection.
+ * legal for establishing a connection to this peer (and make sure that
+ * the address really corresponds to our network connection/settings
+ * and not some potential man-in-the-middle).
*
- * @param addr pointer to the address, may be modified (slightly)
+ * @param addr pointer to the address
* @param addrlen length of addr
* @return GNUNET_OK if this is a plausible address for this peer
* and transport, GNUNET_SYSERR if not
*/
typedef int
- (*GNUNET_TRANSPORT_CheckAddress) (void *cls,
- void *addr, size_t addrlen);
+(*GNUNET_TRANSPORT_CheckAddress) (void *cls,
+ const void *addr, size_t addrlen);
/**
/**
* Function that will be called to check if a binary address
- * for this plugin is well-formed. If clearly needed, patch
- * up information such as port numbers.
- * FIXME: this API will likely change in the near future since
- * it currently does not allow the size of the patched address
- * to be different!
+ * for this plugin is well-formed and corresponds to an
+ * address for THIS peer (as per our configuration). Naturally,
+ * if absolutely necessary, plugins can be a bit conservative in
+ * their answer, but in general plugins should make sure that the
+ * address does not redirect traffic to a 3rd party that might
+ * try to man-in-the-middle our traffic.
*/
GNUNET_TRANSPORT_CheckAddress check_address;
-
/**
* Function that will be called to convert a binary address
* to a string (numeric conversion only).
/**
* Check if the given port is plausible (must be either
* our listen port or our advertised port). If it is
- * neither, we return one of these two ports at random.
+ * neither, we return GNUNET_SYSERR.
*
* @param plugin global variables
* @param in_port port number to check
- * @return either in_port or a more plausible port
+ * @return GNUNET_OK if port is either open_port or adv_port
*/
-static uint16_t
+static int
check_port (struct Plugin *plugin, uint16_t in_port)
{
if ((in_port == plugin->adv_port) || (in_port == plugin->open_port))
- return in_port;
- return (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
- 2) == 0)
- ? plugin->open_port : plugin->adv_port;
+ return GNUNET_OK;
+ return GNUNET_SYSERR;
}
-/**
- * Another peer has suggested an address for this peer and transport
- * plugin. Check that this could be a valid address. This function
- * is not expected to 'validate' the address in the sense of trying to
- * connect to it but simply to see if the binary format is technically
- * legal for establishing a connection.
+/**
+ * Function that will be called to check if a binary address for this
+ * plugin is well-formed and corresponds to an address for THIS peer
+ * (as per our configuration). Naturally, if absolutely necessary,
+ * plugins can be a bit conservative in their answer, but in general
+ * plugins should make sure that the address does not redirect
+ * traffic to a 3rd party that might try to man-in-the-middle our
+ * traffic.
*
* @param cls closure, our 'struct Plugin*'
* @param addr pointer to the address
* and transport, GNUNET_SYSERR if not
*/
static int
-tcp_plugin_check_address (void *cls, void *addr, size_t addrlen)
+tcp_plugin_check_address (void *cls,
+ const void *addr,
+ size_t addrlen)
{
struct Plugin *plugin = cls;
struct IPv4TcpAddress *v4;
if (addrlen == sizeof (struct IPv4TcpAddress))
{
v4 = (struct IPv4TcpAddress *) addr;
- v4->t_port = htons (check_port (plugin, ntohs (v4->t_port)));
+ if (GNUNET_OK !=
+ check_port (plugin, ntohs (v4->t_port)))
+ return GNUNET_SYSERR;
+ /* FIXME: check IP! */
}
else
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- v6->t6_port = htons (check_port (plugin, ntohs (v6->t6_port)));
+ if (GNUNET_OK !=
+ check_port (plugin, ntohs (v6->t6_port)))
+ return GNUNET_SYSERR;
+ /* FIXME: check IP! */
}
return GNUNET_OK;
}
*/
static int
template_plugin_address_suggested (void *cls,
- void *addr, size_t addrlen)
+ const void *addr,
+ size_t addrlen)
{
/* struct Plugin *plugin = cls; */
}
+
+/**
+ * Check if the given port is plausible (must be either
+ * our listen port or our advertised port). If it is
+ * neither, we return GNUNET_SYSERR.
+ *
+ * @param plugin global variables
+ * @param in_port port number to check
+ * @return GNUNET_OK if port is either open_port or adv_port
+ */
+static int
+check_port (struct Plugin *plugin, uint16_t in_port)
+{
+ if (in_port == plugin->port)
+ return GNUNET_OK;
+ return GNUNET_SYSERR;
+}
+
+
/**
- * Another peer has suggested an address for this peer and transport
- * plugin. Check that this could be a valid address. This function
- * is not expected to 'validate' the address in the sense of trying to
- * connect to it but simply to see if the binary format is technically
- * legal for establishing a connection.
+ * Function that will be called to check if a binary address for this
+ * plugin is well-formed and corresponds to an address for THIS peer
+ * (as per our configuration). Naturally, if absolutely necessary,
+ * plugins can be a bit conservative in their answer, but in general
+ * plugins should make sure that the address does not redirect
+ * traffic to a 3rd party that might try to man-in-the-middle our
+ * traffic.
*
* @param cls closure, should be our handle to the Plugin
- * @param addr pointer to the address, may be modified (slightly)
+ * @param addr pointer to the address
* @param addrlen length of addr
* @return GNUNET_OK if this is a plausible address for this peer
* and transport, GNUNET_SYSERR if not
*
*/
static int
-udp_check_address (void *cls, void *addr, size_t addrlen)
+udp_check_address (void *cls,
+ const void *addr,
+ size_t addrlen)
{
struct Plugin *plugin = cls;
- char buf[sizeof (struct sockaddr_in6)];
+ struct IPv4UdpAddress *v4;
+ struct IPv6UdpAddress *v6;
- struct sockaddr_in *v4;
- struct sockaddr_in6 *v6;
-
- if ((addrlen != sizeof (struct sockaddr_in)) &&
- (addrlen != sizeof (struct sockaddr_in6)))
+ if ((addrlen != sizeof (struct IPv4UdpAddress)) &&
+ (addrlen != sizeof (struct IPv6UdpAddress)))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- memcpy (buf, addr, sizeof (struct sockaddr_in6));
- if (addrlen == sizeof (struct sockaddr_in))
+ if (addrlen == sizeof (struct IPv4UdpAddress))
{
- v4 = (struct sockaddr_in *) buf;
- v4->sin_port = htons (plugin->port);
+ v4 = (struct IPv4UdpAddress *) addr;
+ if (GNUNET_OK !=
+ check_port (plugin, ntohs (v4->u_port)))
+ return GNUNET_SYSERR;
+ /* FIXME: check IP! */
}
else
{
- v6 = (struct sockaddr_in6 *) buf;
- v6->sin6_port = htons (plugin->port);
+ v6 = (struct IPv6UdpAddress *) addr;
+ if (IN6_IS_ADDR_LINKLOCAL (&v6->ipv6_addr))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK !=
+ check_port (plugin, ntohs (v6->u6_port)))
+ return GNUNET_SYSERR;
+ /* FIXME: check IP! */
}
-
#if DEBUG_UDP
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
"udp",