2
* $Id: udp.c,v 1.23 2005/06/25 01:37:41 daichik Exp $
4
* Copyright (c) 2004, Raphael Manfredi
6
*----------------------------------------------------------------------
7
* This file is part of gtk-gnutella.
9
* gtk-gnutella is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
14
* gtk-gnutella is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with gtk-gnutella; if not, write to the Free Software
22
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
*----------------------------------------------------------------------
30
* Handling UDP datagrams.
32
* @author Raphael Manfredi
38
RCSID("$Id: udp.c,v 1.23 2005/06/25 01:37:41 daichik Exp $");
46
#include "gnet_stats.h"
54
#include "if/gnet_property_priv.h"
56
#include "lib/endian.h"
58
#include "lib/override.h" /* Must be the last header included */
61
* Look whether the datagram we received is a valid Gnutella packet.
64
udp_is_valid_gnet(struct gnutella_socket *s)
66
struct gnutella_node *n = node_udp_get_ip_port(s->ip, s->port);
67
struct gnutella_header *head;
69
guint32 size; /**< Payload size, from the Gnutella message */
71
if (s->pos < GTA_HEADER_SIZE) {
76
head = (struct gnutella_header *) s->buffer;
77
READ_GUINT32_LE(head->size, size);
79
n->header = *head; /* Struct copy */
80
n->size = s->pos - GTA_HEADER_SIZE; /* Payload size if Gnutella msg */
82
gnet_stats_count_received_header(n);
83
gnet_stats_count_received_payload(n);
85
if (size + GTA_HEADER_SIZE != s->pos) {
86
msg = "Size mismatch";
91
* We only support a subset of Gnutella message from UDP. In particular,
92
* messages like HSEP data, BYE or QRP are not expected!
95
switch (head->function) {
97
case GTA_MSG_INIT_RESPONSE:
99
case GTA_MSG_STANDARD:
100
case GTA_MSG_PUSH_REQUEST:
101
case GTA_MSG_SEARCH_RESULTS:
104
msg = "Queries not yet processed from UDP";
105
goto drop; /* XXX don't handle GUESS queries for now */
107
msg = "Gnutella message not processed from UDP";
114
gnet_stats_count_dropped(n, MSG_DROP_UNEXPECTED);
115
gnet_stats_count_general(GNR_UDP_UNPROCESSED_MESSAGE, 1);
119
gnet_stats_count_general(GNR_UDP_ALIEN_MESSAGE, 1);
124
g_warning("got invalid Gnutella packet from UDP (%s): %s",
125
ip_port_to_gchar(s->ip, s->port), msg);
127
dump_hex(stderr, "UDP datagram", s->buffer, s->pos);
134
* Notification from the socket layer that we got a new datagram.
137
udp_received(struct gnutella_socket *s)
139
gboolean bogus = FALSE;
142
* If reply comes from the NTP port, notify that they're running NTP.
145
if (s->ip == 0x7f000001 && s->port == NTP_PORT) { /* from 127.0.0.1:123 */
151
* This must be regular Gnutella traffic then.
154
inet_udp_got_incoming(s->ip);
155
bws_udp_count_read(s->pos);
158
* If we get traffic from a bogus IP (unroutable), warn, for now.
161
if (bogons_check(s->ip)) {
165
g_warning("UDP datagram (%d byte%s) received from bogus IP %s",
166
(gint) s->pos, s->pos == 1 ? "" : "s", ip_to_gchar(s->ip));
168
gnet_stats_count_general(GNR_UDP_BOGUS_SOURCE_IP, 1);
171
if (!udp_is_valid_gnet(s))
175
* Process message as if it had been received from regular Gnet by
176
* another node, only we'll use a special "pseudo UDP node" as origin.
180
printf("UDP got %s from %s%s\n", gmsg_infostr_full(s->buffer),
181
bogus ? "BOGUS " : "", ip_port_to_gchar(s->ip, s->port));
187
* Send a datagram to the specified node, made of `len' bytes from `buf',
188
* forming a valid Gnutella message.
190
void udp_send_msg(gnutella_node_t *n, gpointer buf, gint len)
192
g_assert(NODE_IS_UDP(n));
194
mq_udp_node_putq(n->outq, gmsg_to_pmsg(buf, len), n);
198
* Send a Gnutella ping to the specified host via UDP, using the
202
udp_connect_back(guint32 ip, guint16 port, const gchar *muid)
204
struct gnutella_msg_init *m;
205
struct gnutella_node *n = node_udp_get_ip_port(ip, port);
211
m = build_ping_msg(muid, 1, FALSE, &size);
213
mq_udp_node_putq(n->outq, gmsg_to_pmsg(m, size), n);
216
printf("UDP queued connect-back PING %s (%u bytes) to %s\n",
217
guid_hex_str(muid), size, ip_port_to_gchar(ip, port));
221
* Send a Gnutella ping to the specified host.
224
udp_send_ping(guint32 ip, guint16 port)
226
struct gnutella_msg_init *m;
227
struct gnutella_node *n = node_udp_get_ip_port(ip, port);
233
m = build_ping_msg(NULL, 1, FALSE, &size);
234
udp_send_msg(n, m, size);
237
/* vi: set ts=4 sw=4 cindent: */