diff src/message/push.c @ 0:d39e1d0d75b6

initial add
author paulo@hit-nxdomain.opendns.com
date Sat, 20 Feb 2010 21:18:28 -0800
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/message/push.c	Sat Feb 20 21:18:28 2010 -0800
     1.3 @@ -0,0 +1,216 @@
     1.4 +/*
     1.5 + * $Id: push.c,v 1.3 2004/03/24 06:36:12 hipnod Exp $
     1.6 + *
     1.7 + * Copyright (C) 2001-2003 giFT project (gift.sourceforge.net)
     1.8 + *
     1.9 + * This program is free software; you can redistribute it and/or modify it
    1.10 + * under the terms of the GNU General Public License as published by the
    1.11 + * Free Software Foundation; either version 2, or (at your option) any
    1.12 + * later version.
    1.13 + *
    1.14 + * This program is distributed in the hope that it will be useful, but
    1.15 + * WITHOUT ANY WARRANTY; without even the implied warranty of
    1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.17 + * General Public License for more details.
    1.18 + */
    1.19 +
    1.20 +#include "gt_gnutella.h"
    1.21 +#include "msg_handler.h"
    1.22 +
    1.23 +#include "gt_accept.h"
    1.24 +#include "gt_share_file.h"
    1.25 +#include "gt_share.h"
    1.26 +
    1.27 +/*****************************************************************************/
    1.28 +
    1.29 +typedef struct giv_connect
    1.30 +{
    1.31 +	uint32_t   index;
    1.32 +	char      *filename;
    1.33 +} giv_connect_t;
    1.34 +
    1.35 +/*****************************************************************************/
    1.36 +
    1.37 +static giv_connect_t *giv_connect_alloc (uint32_t index, const char *filename)
    1.38 +{
    1.39 +	giv_connect_t *giv;
    1.40 +
    1.41 +	if (!(giv = malloc (sizeof(giv_connect_t))))
    1.42 +		return NULL;
    1.43 +
    1.44 +	if (filename)
    1.45 +		giv->filename = STRDUP (filename);
    1.46 +	else
    1.47 +		giv->filename = NULL;
    1.48 +
    1.49 +	giv->index = index;
    1.50 +
    1.51 +	return giv;
    1.52 +}
    1.53 +
    1.54 +static void giv_connect_free (giv_connect_t *giv)
    1.55 +{
    1.56 +	if (!giv)
    1.57 +		return;
    1.58 +
    1.59 +	free (giv->filename);
    1.60 +	free (giv);
    1.61 +}
    1.62 +
    1.63 +static char *giv_connect_str (giv_connect_t *giv)
    1.64 +{
    1.65 +	String *s;
    1.66 +
    1.67 +	if (!(s = string_new (NULL, 0, 0, TRUE)))
    1.68 +		return NULL;
    1.69 +
    1.70 +	string_append  (s, "GIV ");
    1.71 +	string_appendf (s, "%u:", giv->index);
    1.72 +	string_appendf (s, "%s/", gt_guid_str (GT_SELF_GUID));
    1.73 +
    1.74 +	if (giv->filename && !string_isempty (giv->filename))
    1.75 +		string_append (s, giv->filename);
    1.76 +
    1.77 +	string_append (s, "\n\n");
    1.78 +
    1.79 +	return string_free_keep (s);
    1.80 +}
    1.81 +
    1.82 +/*****************************************************************************/
    1.83 +
    1.84 +static void handle_giv_connect (int fd, input_id id, TCPC *c,
    1.85 +                                giv_connect_t *giv)
    1.86 +{
    1.87 +	char *str;
    1.88 +	int   ret;
    1.89 +
    1.90 +	if (MSG_DEBUG)
    1.91 +		GT->DBGFN (GT, "entered");
    1.92 +
    1.93 +	if (net_sock_error (fd))
    1.94 +	{
    1.95 +		if (MSG_DEBUG)
    1.96 +			GT->DBGFN (GT, "error connecting back: %s", GIFT_NETERROR ());
    1.97 +
    1.98 +		tcp_close (c);
    1.99 +		return;
   1.100 +	}
   1.101 +
   1.102 +	/* restore the index */
   1.103 +	c->udata = NULL;
   1.104 +	str = giv_connect_str (giv);
   1.105 +
   1.106 +	if (MSG_DEBUG)
   1.107 +		GT->DBGSOCK (GT, c, "sending GIV response: %s", str);
   1.108 +
   1.109 +	ret = tcp_send (c, str, strlen (str));
   1.110 +	free (str);
   1.111 +
   1.112 +	if (ret <= 0)
   1.113 +	{
   1.114 +		if (MSG_DEBUG)
   1.115 +			GT->DBGFN (GT, "error sending: %s", GIFT_NETERROR ());
   1.116 +
   1.117 +		tcp_close (c);
   1.118 +		return;
   1.119 +	}
   1.120 +
   1.121 +	/* use this connection for something */
   1.122 +	input_remove (id);
   1.123 +	input_add (c->fd, c, INPUT_READ,
   1.124 +	           (InputCallback)gt_handshake_dispatch_incoming, TIMEOUT_DEF);
   1.125 +}
   1.126 +
   1.127 +static void giv_connect (int fd, input_id id, TCPC *c)
   1.128 +{
   1.129 +	giv_connect_t *giv;
   1.130 +
   1.131 +	giv = c->udata;
   1.132 +	handle_giv_connect (fd, id, c, giv);
   1.133 +
   1.134 +	giv_connect_free (giv);
   1.135 +}
   1.136 +
   1.137 +static void gt_giv_request (GtNode *src, uint32_t index, in_addr_t ip,
   1.138 +                            in_port_t port, uint8_t hops)
   1.139 +{
   1.140 +	giv_connect_t *giv;
   1.141 +	char          *filename = NULL;
   1.142 +	Share         *share;
   1.143 +	GtShare       *gt_share;
   1.144 +	TCPC          *c;
   1.145 +
   1.146 +	if (MSG_DEBUG)
   1.147 +		GT->DBGFN (GT, "entered");
   1.148 +
   1.149 +	/* if the pushed IP address is local, forget about it */
   1.150 +	if (gt_is_local_ip (ip, src->ip))
   1.151 +		return;
   1.152 +
   1.153 +	/* special case: if the node we got the giv from is local
   1.154 +	 * and the giv is from them (hops=0), don't connect to the
   1.155 +	 * external address but the internal */
   1.156 +	if (hops == 0 && gt_is_local_ip (src->ip, ip))
   1.157 +		ip = src->ip;
   1.158 +
   1.159 +	/*
   1.160 +	 * Look for the index in the local shared database, if it is found
   1.161 +	 * keep track of the filename.
   1.162 +	 */
   1.163 +	if ((share = gt_share_local_lookup_by_index (index, NULL)) != NULL &&
   1.164 +	    (gt_share = share_get_udata (share, GT->name)) != NULL)
   1.165 +	{
   1.166 +		filename = gt_share->filename;
   1.167 +	}
   1.168 +
   1.169 +	if (!(giv = giv_connect_alloc (index, filename)))
   1.170 +		return;
   1.171 +
   1.172 +	if (!(c = tcp_open (ip, port, FALSE)))
   1.173 +	{
   1.174 +		giv_connect_free (giv);
   1.175 +		return;
   1.176 +	}
   1.177 +
   1.178 +	c->udata = giv;
   1.179 +
   1.180 +	input_add (c->fd, c, INPUT_WRITE,
   1.181 +	           (InputCallback)giv_connect, TIMEOUT_DEF);
   1.182 +}
   1.183 +
   1.184 +GT_MSG_HANDLER(gt_msg_push)
   1.185 +{
   1.186 +	gt_guid_t  *client_guid;
   1.187 +	uint32_t    index;
   1.188 +	uint32_t    ip;
   1.189 +	uint16_t    port;
   1.190 +	uint8_t     hops;
   1.191 +
   1.192 +	if (MSG_DEBUG)
   1.193 +		GT->DBGFN (GT, "entered");
   1.194 +
   1.195 +	client_guid = gt_packet_get_ustr   (packet, 16);
   1.196 +	index       = gt_packet_get_uint32 (packet);
   1.197 +	ip          = gt_packet_get_ip     (packet);
   1.198 +	port        = gt_packet_get_port   (packet);
   1.199 +
   1.200 +	hops = gt_packet_hops (packet);
   1.201 +
   1.202 +	if (MSG_DEBUG)
   1.203 +	{
   1.204 +		GT->DBGSOCK (GT, c, "client_guid=%s index=%d ip=%s port=%hu",
   1.205 +		             gt_guid_str (client_guid), index, net_ip_str (ip), port);
   1.206 +	}
   1.207 +
   1.208 +	if (gt_guid_cmp (client_guid, GT_SELF_GUID) == 0)
   1.209 +	{
   1.210 +		/* TODO: we should not respond if we get a lot of these */
   1.211 +		gt_giv_request (GT_NODE(c), index, ip, port, hops);
   1.212 +		return;
   1.213 +	}
   1.214 +
   1.215 +#if 0
   1.216 +	if ((dst_c = push_cache_lookup (client->guid)))
   1.217 +		gt_route_forward_packet (dst_c, packet);
   1.218 +#endif
   1.219 +}