Mercurial > hg > index.fcgi > gift-gnutella > gift-gnutella-0.0.11-1pba
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 +}