Mercurial > hg > index.fcgi > gift-gnutella > gift-gnutella-0.0.11-1pba
diff src/message/vendor.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/vendor.c Sat Feb 20 21:18:28 2010 -0800 1.3 @@ -0,0 +1,283 @@ 1.4 +/* 1.5 + * $Id: vendor.c,v 1.6 2004/03/26 11:44:13 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 "message/msg_handler.h" 1.22 + 1.23 +#include "gt_connect.h" /* gt_connect_test */ 1.24 +#include "gt_bind.h" 1.25 + 1.26 +#include "gt_utils.h" /* make_str */ 1.27 + 1.28 +#include "transfer/push_proxy.h" 1.29 + 1.30 +/*****************************************************************************/ 1.31 + 1.32 +#define EMPTY_VENDOR { 0, 0, 0, 0 } 1.33 + 1.34 +#define vmsg_name(name) \ 1.35 + name##_struct 1.36 + 1.37 +#define declare_vmsg(name,vendor,id) \ 1.38 + const struct gt_vendor_msg vmsg_name(name) = { vendor, id }; \ 1.39 + const struct gt_vendor_msg *name = &name##_struct; 1.40 + 1.41 +/* Globally visible vendor message structs */ 1.42 +declare_vmsg(GT_VMSG_MESSAGES_SUPP, EMPTY_VENDOR, 0); 1.43 +declare_vmsg(GT_VMSG_HOPS_FLOW, "BEAR", 4); 1.44 +declare_vmsg(GT_VMSG_TCP_CONNECT_BACK, "BEAR", 7); 1.45 +declare_vmsg(GT_VMSG_PUSH_PROXY_REQ, "LIME", 21); 1.46 +declare_vmsg(GT_VMSG_PUSH_PROXY_ACK, "LIME", 22); 1.47 + 1.48 +/*****************************************************************************/ 1.49 + 1.50 +static GT_MSG_HANDLER(gt_msg_messages_supported); 1.51 +static GT_MSG_HANDLER(gt_msg_hops_flow); 1.52 +static GT_MSG_HANDLER(gt_msg_tcp_connect_back); 1.53 +static GT_MSG_HANDLER(gt_msg_push_proxy_request); 1.54 +static GT_MSG_HANDLER(gt_msg_push_proxy_acknowledgement); 1.55 + 1.56 +/*****************************************************************************/ 1.57 + 1.58 +struct gt_vendor_table 1.59 +{ 1.60 + const struct gt_vendor_msg *msg; 1.61 + GtMessageHandler func; 1.62 + uint16_t version; 1.63 + BOOL in_msgs_supported; /* inside MessagesSupported */ 1.64 +}; 1.65 + 1.66 +static struct gt_vendor_table vendor_table[] = 1.67 +{ 1.68 + { &vmsg_name(GT_VMSG_MESSAGES_SUPP), gt_msg_messages_supported, 1.69 + 1, FALSE }, 1.70 + { &vmsg_name(GT_VMSG_HOPS_FLOW), gt_msg_hops_flow, 1.71 + 1, FALSE /*TODO: support receving*/ }, 1.72 + { &vmsg_name(GT_VMSG_TCP_CONNECT_BACK), gt_msg_tcp_connect_back, 1.73 + 1, TRUE }, 1.74 + { &vmsg_name(GT_VMSG_PUSH_PROXY_REQ), gt_msg_push_proxy_request, 1.75 + 2, TRUE }, 1.76 + { &vmsg_name(GT_VMSG_PUSH_PROXY_ACK), gt_msg_push_proxy_acknowledgement, 1.77 + 2, FALSE }, 1.78 +}; 1.79 + 1.80 +static const size_t nr_vmsgs = sizeof(vendor_table) / sizeof(vendor_table[0]); 1.81 + 1.82 +/*****************************************************************************/ 1.83 + 1.84 +static void vmsg_init (struct gt_vendor_msg *msg, 1.85 + unsigned char *vendor_id, uint16_t id) 1.86 +{ 1.87 + /* initialize to zero because of potential structure alignment issues */ 1.88 + memset (msg, 0, sizeof(struct gt_vendor_msg)); 1.89 + 1.90 + memcpy (&msg->vendor_id, vendor_id, 4); 1.91 + msg->id = id; 1.92 +} 1.93 + 1.94 +static void append_vmsg (GtPacket *pkt, const struct gt_vendor_msg *msg, 1.95 + uint16_t ver) 1.96 +{ 1.97 + gt_packet_put_ustr (pkt, msg->vendor_id, 4); 1.98 + gt_packet_put_uint16 (pkt, msg->id); 1.99 + gt_packet_put_uint16 (pkt, ver); 1.100 +} 1.101 + 1.102 +void gt_vmsg_send_supported (GtNode *node) 1.103 +{ 1.104 + GtPacket *pkt; 1.105 + int i; 1.106 + uint16_t vector_len = 0; 1.107 + 1.108 + if (!dataset_lookupstr (node->hdr, "vendor-message")) 1.109 + return; 1.110 + 1.111 + if (!(pkt = gt_packet_vendor (GT_VMSG_MESSAGES_SUPP))) 1.112 + return; 1.113 + 1.114 + gt_packet_put_uint16 (pkt, 0); 1.115 + 1.116 + for (i = 0; i < nr_vmsgs; i++) 1.117 + { 1.118 + if (vendor_table[i].in_msgs_supported) 1.119 + { 1.120 + vector_len++; 1.121 + append_vmsg (pkt, vendor_table[i].msg, vendor_table[i].version); 1.122 + } 1.123 + } 1.124 + 1.125 + /* XXX: packet put_xxx functions don't work with gt_packet_seek :( */ 1.126 + vector_len = htovl (vector_len); 1.127 + memcpy (&pkt->data[GNUTELLA_HDR_LEN + VMSG_HDR_LEN], &vector_len, 2); 1.128 + 1.129 + if (gt_packet_error (pkt)) 1.130 + { 1.131 + gt_packet_free (pkt); 1.132 + return; 1.133 + } 1.134 + 1.135 + GT->DBGSOCK (GT, GT_CONN(node), "sending MessagesSupported"); 1.136 + 1.137 + gt_packet_send (GT_CONN(node), pkt); 1.138 + gt_packet_free (pkt); 1.139 +} 1.140 + 1.141 +/*****************************************************************************/ 1.142 + 1.143 +GT_MSG_HANDLER(gt_msg_vendor) 1.144 +{ 1.145 + struct gt_vendor_msg vmsg; 1.146 + unsigned char *vendor; 1.147 + int i; 1.148 + uint16_t id; 1.149 + uint16_t version; 1.150 + 1.151 + if (gt_packet_hops (packet) != 0 && gt_packet_ttl (packet) != 1) 1.152 + return; 1.153 + 1.154 + vendor = gt_packet_get_ustr (packet, 4); 1.155 + id = gt_packet_get_uint16 (packet); 1.156 + version = gt_packet_get_uint16 (packet); 1.157 + 1.158 + /* initialize a copy for making a single call to memcmp */ 1.159 + vmsg_init (&vmsg, vendor, id); 1.160 + 1.161 + if (gt_packet_error (packet)) 1.162 + { 1.163 + if (MSG_DEBUG) 1.164 + GT->DBGSOCK (GT, c, "Error parsing vendor message"); 1.165 + 1.166 + return; 1.167 + } 1.168 + 1.169 + for (i = 0; i < nr_vmsgs; i++) 1.170 + { 1.171 + if (memcmp (vendor_table[i].msg, &vmsg, sizeof(vmsg)) == 0 && 1.172 + version <= vendor_table[i].version) 1.173 + { 1.174 + vendor_table[i].func (MSG_HANDLER_ARG_NAMES); 1.175 + return; 1.176 + } 1.177 + } 1.178 + 1.179 + if (MSG_DEBUG) 1.180 + { 1.181 + GT->DBGSOCK (GT, c, "No handler for vendor message %s/%dv%d", 1.182 + make_str (vendor, 4), id, version); 1.183 + } 1.184 +} 1.185 + 1.186 +/*****************************************************************************/ 1.187 + 1.188 +static struct gt_vendor_table *find_in_vmsg_table (gt_vendor_msg_t *vmsg) 1.189 +{ 1.190 + int i; 1.191 + 1.192 + for (i = 0; i < nr_vmsgs; i++) 1.193 + { 1.194 + if (memcmp (vendor_table[i].msg, vmsg, sizeof(*vmsg)) == 0) 1.195 + return &vendor_table[i]; 1.196 + } 1.197 + 1.198 + return NULL; 1.199 +} 1.200 + 1.201 +static GT_MSG_HANDLER(gt_msg_messages_supported) 1.202 +{ 1.203 + gt_vendor_msg_t vmsg; 1.204 + unsigned char *vendor_id; 1.205 + int i; 1.206 + uint16_t id; 1.207 + uint16_t version; 1.208 + uint16_t vector_len; 1.209 + 1.210 + vector_len = gt_packet_get_uint16 (packet); 1.211 + 1.212 + if (gt_packet_error (packet)) 1.213 + return; 1.214 + 1.215 + /* 1.216 + * Track the supported messages in a dataset on this node. 1.217 + */ 1.218 + for (i = 0; i < vector_len; i++) 1.219 + { 1.220 + struct gt_vendor_table *entry; 1.221 + 1.222 + vendor_id = gt_packet_get_ustr (packet, 4); 1.223 + id = gt_packet_get_uint16 (packet); 1.224 + version = gt_packet_get_uint16 (packet); 1.225 + 1.226 + if (gt_packet_error (packet)) 1.227 + break; 1.228 + 1.229 + vmsg_init (&vmsg, vendor_id, id); 1.230 + 1.231 + if (!(entry = find_in_vmsg_table (&vmsg))) 1.232 + continue; 1.233 + 1.234 + /* only send the minimum supported by both ends to this node */ 1.235 + version = MIN (version, entry->version); 1.236 + 1.237 + /* track support for this vendor message */ 1.238 + dataset_insert (&node->vmsgs_supported, &vmsg, sizeof(vmsg), 1.239 + &version, sizeof(version)); 1.240 + } 1.241 + 1.242 + /* send our batch of vendor messages now */ 1.243 + gt_bind_completed_connection (node); 1.244 +} 1.245 + 1.246 +/*****************************************************************************/ 1.247 + 1.248 +static GT_MSG_HANDLER(gt_msg_hops_flow) 1.249 +{ 1.250 +} 1.251 + 1.252 +/*****************************************************************************/ 1.253 + 1.254 +static GT_MSG_HANDLER(gt_msg_tcp_connect_back) 1.255 +{ 1.256 + in_port_t port; 1.257 + 1.258 + port = gt_packet_get_port (packet); 1.259 + 1.260 + if (!port) 1.261 + return; 1.262 + 1.263 + gt_connect_test (node, port); 1.264 +} 1.265 + 1.266 +/*****************************************************************************/ 1.267 + 1.268 +static GT_MSG_HANDLER(gt_msg_push_proxy_request) 1.269 +{ 1.270 + return; 1.271 +} 1.272 + 1.273 +static GT_MSG_HANDLER(gt_msg_push_proxy_acknowledgement) 1.274 +{ 1.275 + in_addr_t ip; 1.276 + in_port_t port; 1.277 + 1.278 + ip = gt_packet_get_ip (packet); 1.279 + port = gt_packet_get_port (packet); 1.280 + 1.281 + if (gt_packet_error (packet)) 1.282 + return; 1.283 + 1.284 + gt_push_proxy_del (node); 1.285 + gt_push_proxy_add (node, ip, port); 1.286 +}