1 /*
2 * Copyright (C) 2000 Ross Combs (rocombs@cs.nmsu.edu)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18 #include "common/setup_before.h"
19 #include <stdio.h>
20 #ifdef HAVE_UNISTD_H
21 # include <unistd.h>
22 #endif
23 #ifdef HAVE_STRING_H
24 # include <string.h>
25 #else
26 # ifdef HAVE_STRINGS_H
27 # include <strings.h>
28 # endif
29 # ifdef HAVE_MEMORY_H
30 # include <memory.h>
31 # endif
32 #endif
33 #include "compat/memset.h"
34 #include <errno.h>
35 #include "compat/strerror.h"
36 #ifdef HAVE_SYS_TYPES_H
37 # include <sys/types.h>
38 #endif
39 #ifdef HAVE_SYS_SOCKET_H
40 # include <sys/socket.h>
41 #endif
42 #include "compat/socket.h"
43 #ifdef HAVE_SYS_PARAM_H
44 # include <sys/param.h>
45 #endif
46 #ifdef HAVE_NETINET_IN_H
47 # include <netinet/in.h>
48 #endif
49 #include "compat/netinet_in.h"
50 #ifdef HAVE_ARPA_INET_H
51 # include <arpa/inet.h> /* FIXME: probably not needed... do some systems put types in here or something? */
52 #endif
53 #include "compat/psock.h"
54 #include "common/packet.h"
55 #include "common/bn_type.h"
56 #include "common/udp_protocol.h"
57 #include "connection.h"
58 #include "common/addr.h"
59 #include "common/tag.h"
60 #include "common/hexdump.h"
61 #include "common/eventlog.h"
62 #include "udptest_send.h"
63 #include "common/setup_after.h"
64
65
66 extern FILE * hexstrm; /* from main.c */
67
68
udptest_send(t_connection const * c)69 extern int udptest_send(t_connection const * c)
70 {
71 t_packet * upacket;
72 struct sockaddr_in caddr;
73 unsigned int tries,successes;
74
75 memset(&caddr,0,sizeof(caddr));
76 caddr.sin_family = PSOCK_AF_INET;
77 caddr.sin_port = htons(conn_get_game_port(c));
78 caddr.sin_addr.s_addr = htonl(conn_get_game_addr(c));
79
80 for (tries=successes=0; successes!=2 && tries<5; tries++)
81 {
82 if (!(upacket = packet_create(packet_class_udp)))
83 {
84 eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not allocate memory for packet",conn_get_socket(c));
85 continue;
86 }
87 packet_set_size(upacket,sizeof(t_server_udptest));
88 packet_set_type(upacket,SERVER_UDPTEST);
89 bn_int_tag_set(&upacket->u.server_udptest.bnettag,BNETTAG);
90
91 if (hexstrm)
92 {
93 fprintf(hexstrm,"%d: send class=%s[0x%02x] type=%s[0x%04x] ",
94 conn_get_game_socket(c),
95 packet_get_class_str(upacket),(unsigned int)packet_get_class(upacket),
96 packet_get_type_str(upacket,packet_dir_from_server),packet_get_type(upacket));
97 fprintf(hexstrm,"from=%s ",
98 addr_num_to_addr_str(conn_get_game_addr(c),conn_get_game_port(c)));
99 fprintf(hexstrm,"to=%s ",
100 addr_num_to_addr_str(ntohl(caddr.sin_addr.s_addr),ntohs(caddr.sin_port)));
101 fprintf(hexstrm,"length=%u\n",
102 packet_get_size(upacket));
103 hexdump(hexstrm,packet_get_raw_data(upacket,0),packet_get_size(upacket));
104 }
105
106 if (psock_sendto(conn_get_game_socket(c),
107 packet_get_raw_data_const(upacket,0),packet_get_size(upacket),
108 0,(struct sockaddr *)&caddr,(psock_t_socklen)sizeof(caddr))!=(int)packet_get_size(upacket))
109 eventlog(eventlog_level_error,__FUNCTION__,"[%d] failed to send UDPTEST to %s (attempt %u) (psock_sendto: %s)",conn_get_socket(c),addr_num_to_addr_str(ntohl(caddr.sin_addr.s_addr),conn_get_game_port(c)),tries+1,pstrerror(psock_errno()));
110 else
111 successes++;
112
113 packet_del_ref(upacket);
114 }
115
116 if (successes!=2)
117 return -1;
118
119 return 0;
120 }
121