view 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 source
1 /*
2 * $Id: push.c,v 1.3 2004/03/24 06:36:12 hipnod Exp $
3 *
4 * Copyright (C) 2001-2003 giFT project (gift.sourceforge.net)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
17 #include "gt_gnutella.h"
18 #include "msg_handler.h"
20 #include "gt_accept.h"
21 #include "gt_share_file.h"
22 #include "gt_share.h"
24 /*****************************************************************************/
26 typedef struct giv_connect
27 {
28 uint32_t index;
29 char *filename;
30 } giv_connect_t;
32 /*****************************************************************************/
34 static giv_connect_t *giv_connect_alloc (uint32_t index, const char *filename)
35 {
36 giv_connect_t *giv;
38 if (!(giv = malloc (sizeof(giv_connect_t))))
39 return NULL;
41 if (filename)
42 giv->filename = STRDUP (filename);
43 else
44 giv->filename = NULL;
46 giv->index = index;
48 return giv;
49 }
51 static void giv_connect_free (giv_connect_t *giv)
52 {
53 if (!giv)
54 return;
56 free (giv->filename);
57 free (giv);
58 }
60 static char *giv_connect_str (giv_connect_t *giv)
61 {
62 String *s;
64 if (!(s = string_new (NULL, 0, 0, TRUE)))
65 return NULL;
67 string_append (s, "GIV ");
68 string_appendf (s, "%u:", giv->index);
69 string_appendf (s, "%s/", gt_guid_str (GT_SELF_GUID));
71 if (giv->filename && !string_isempty (giv->filename))
72 string_append (s, giv->filename);
74 string_append (s, "\n\n");
76 return string_free_keep (s);
77 }
79 /*****************************************************************************/
81 static void handle_giv_connect (int fd, input_id id, TCPC *c,
82 giv_connect_t *giv)
83 {
84 char *str;
85 int ret;
87 if (MSG_DEBUG)
88 GT->DBGFN (GT, "entered");
90 if (net_sock_error (fd))
91 {
92 if (MSG_DEBUG)
93 GT->DBGFN (GT, "error connecting back: %s", GIFT_NETERROR ());
95 tcp_close (c);
96 return;
97 }
99 /* restore the index */
100 c->udata = NULL;
101 str = giv_connect_str (giv);
103 if (MSG_DEBUG)
104 GT->DBGSOCK (GT, c, "sending GIV response: %s", str);
106 ret = tcp_send (c, str, strlen (str));
107 free (str);
109 if (ret <= 0)
110 {
111 if (MSG_DEBUG)
112 GT->DBGFN (GT, "error sending: %s", GIFT_NETERROR ());
114 tcp_close (c);
115 return;
116 }
118 /* use this connection for something */
119 input_remove (id);
120 input_add (c->fd, c, INPUT_READ,
121 (InputCallback)gt_handshake_dispatch_incoming, TIMEOUT_DEF);
122 }
124 static void giv_connect (int fd, input_id id, TCPC *c)
125 {
126 giv_connect_t *giv;
128 giv = c->udata;
129 handle_giv_connect (fd, id, c, giv);
131 giv_connect_free (giv);
132 }
134 static void gt_giv_request (GtNode *src, uint32_t index, in_addr_t ip,
135 in_port_t port, uint8_t hops)
136 {
137 giv_connect_t *giv;
138 char *filename = NULL;
139 Share *share;
140 GtShare *gt_share;
141 TCPC *c;
143 if (MSG_DEBUG)
144 GT->DBGFN (GT, "entered");
146 /* if the pushed IP address is local, forget about it */
147 if (gt_is_local_ip (ip, src->ip))
148 return;
150 /* special case: if the node we got the giv from is local
151 * and the giv is from them (hops=0), don't connect to the
152 * external address but the internal */
153 if (hops == 0 && gt_is_local_ip (src->ip, ip))
154 ip = src->ip;
156 /*
157 * Look for the index in the local shared database, if it is found
158 * keep track of the filename.
159 */
160 if ((share = gt_share_local_lookup_by_index (index, NULL)) != NULL &&
161 (gt_share = share_get_udata (share, GT->name)) != NULL)
162 {
163 filename = gt_share->filename;
164 }
166 if (!(giv = giv_connect_alloc (index, filename)))
167 return;
169 if (!(c = tcp_open (ip, port, FALSE)))
170 {
171 giv_connect_free (giv);
172 return;
173 }
175 c->udata = giv;
177 input_add (c->fd, c, INPUT_WRITE,
178 (InputCallback)giv_connect, TIMEOUT_DEF);
179 }
181 GT_MSG_HANDLER(gt_msg_push)
182 {
183 gt_guid_t *client_guid;
184 uint32_t index;
185 uint32_t ip;
186 uint16_t port;
187 uint8_t hops;
189 if (MSG_DEBUG)
190 GT->DBGFN (GT, "entered");
192 client_guid = gt_packet_get_ustr (packet, 16);
193 index = gt_packet_get_uint32 (packet);
194 ip = gt_packet_get_ip (packet);
195 port = gt_packet_get_port (packet);
197 hops = gt_packet_hops (packet);
199 if (MSG_DEBUG)
200 {
201 GT->DBGSOCK (GT, c, "client_guid=%s index=%d ip=%s port=%hu",
202 gt_guid_str (client_guid), index, net_ip_str (ip), port);
203 }
205 if (gt_guid_cmp (client_guid, GT_SELF_GUID) == 0)
206 {
207 /* TODO: we should not respond if we get a lot of these */
208 gt_giv_request (GT_NODE(c), index, ip, port, hops);
209 return;
210 }
212 #if 0
213 if ((dst_c = push_cache_lookup (client->guid)))
214 gt_route_forward_packet (dst_c, packet);
215 #endif
216 }