aboutsummaryrefslogtreecommitdiff
path: root/src/KINDLE/i_network.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/KINDLE/i_network.c')
-rw-r--r--src/KINDLE/i_network.c292
1 files changed, 292 insertions, 0 deletions
diff --git a/src/KINDLE/i_network.c b/src/KINDLE/i_network.c
new file mode 100644
index 0000000..4730d50
--- /dev/null
+++ b/src/KINDLE/i_network.c
@@ -0,0 +1,292 @@
1/* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
3 *
4 *
5 * PrBoom: a Doom port merged with LxDoom and LSDLDoom
6 * based on BOOM, a modified and improved DOOM engine
7 * Copyright (C) 1999 by
8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9 * Copyright (C) 1999-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
11 * Copyright 2005, 2006 by
12 * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 * 02111-1307, USA.
28 *
29 * DESCRIPTION:
30 * Low level UDP network interface. This is shared between the server
31 * and client, with SERVER defined for the former to select some extra
32 * functions. Handles socket creation, and packet send and receive.
33 *
34 *-----------------------------------------------------------------------------*/
35
36#ifdef HAVE_CONFIG_H
37# include "config.h"
38#endif
39#ifdef HAVE_NETINET_IN_H
40# include <netinet/in.h>
41#endif
42#include <stdlib.h>
43#include <errno.h>
44#ifdef HAVE_UNISTD_H
45#include <unistd.h>
46#endif
47#include <stdio.h>
48#include <fcntl.h>
49#include <string.h>
50
51#ifdef HAVE_NET
52
53#include "SDL.h"
54#include "SDL_net.h"
55
56#include "protocol.h"
57#include "i_network.h"
58#include "lprintf.h"
59//#include "doomstat.h"
60
61/* cph -
62 * Each client will either use the IPv4 socket or the IPv6 socket
63 * Each server will use whichever or both that are available
64 */
65UDP_CHANNEL sentfrom;
66IPaddress sentfrom_addr;
67UDP_SOCKET udp_socket;
68
69/* Statistics */
70size_t sentbytes, recvdbytes;
71
72UDP_PACKET *udp_packet;
73
74/* I_ShutdownNetwork
75 *
76 * Shutdown the network code
77 */
78void I_ShutdownNetwork(void)
79{
80 SDLNet_FreePacket(udp_packet);
81 SDLNet_Quit();
82}
83
84/* I_InitNetwork
85 *
86 * Sets up the network code
87 */
88void I_InitNetwork(void)
89{
90 SDLNet_Init();
91 atexit(I_ShutdownNetwork);
92 udp_packet = SDLNet_AllocPacket(10000);
93}
94
95UDP_PACKET *I_AllocPacket(int size)
96{
97 return(SDLNet_AllocPacket(size));
98}
99
100void I_FreePacket(UDP_PACKET *packet)
101{
102 SDLNet_FreePacket(packet);
103}
104
105
106/* cph - I_WaitForPacket - use select(2) via SDL_net's interface
107 * No more I_uSleep loop kludge */
108
109void I_WaitForPacket(int ms)
110{
111 SDLNet_SocketSet ss = SDLNet_AllocSocketSet(1);
112 SDLNet_UDP_AddSocket(ss, udp_socket);
113 SDLNet_CheckSockets(ss,ms);
114 SDLNet_FreeSocketSet(ss);
115#if (defined _WIN32 && !defined PRBOOM_SERVER)
116 I_UpdateConsole();
117#endif
118}
119
120/* I_ConnectToServer
121 *
122 * Connect to a server
123 */
124IPaddress serverIP;
125
126int I_ConnectToServer(const char *serv)
127{
128 char server[500], *p;
129 Uint16 port;
130
131 /* Split serv into address and port */
132 if (strlen(serv)>500) return 0;
133 strcpy(server,serv);
134 p = strchr(server, ':');
135 if(p)
136 {
137 *p++ = '\0';
138 port = atoi(p);
139 }
140 else
141 port = 5030; /* Default server port */
142
143 SDLNet_ResolveHost(&serverIP, server, port);
144 if ( serverIP.host == INADDR_NONE )
145 return -1;
146
147 if (SDLNet_UDP_Bind(udp_socket, 0, &serverIP) == -1)
148 return -1;
149
150 return 0;
151}
152
153/* I_Disconnect
154 *
155 * Disconnect from server
156 */
157void I_Disconnect(void)
158{
159/* int i;
160 UDP_PACKET *packet;
161 packet_header_t *pdata = (packet_header_t *)packet->data;
162 packet = I_AllocPacket(sizeof(packet_header_t) + 1);
163
164 packet->data[sizeof(packet_header_t)] = consoleplayer;
165 pdata->type = PKT_QUIT; pdata->tic = gametic;
166
167 for (i=0; i<4; i++) {
168 I_SendPacket(packet);
169 I_uSleep(10000);
170 }
171 I_FreePacket(packet);*/
172 SDLNet_UDP_Unbind(udp_socket, 0);
173}
174
175/*
176 * I_Socket
177 *
178 * Sets the given socket non-blocking, binds to the given port, or first
179 * available if none is given
180 */
181UDP_SOCKET I_Socket(Uint16 port)
182{
183 if(port)
184 return (SDLNet_UDP_Open(port));
185 else {
186 UDP_SOCKET sock;
187 port = IPPORT_RESERVED;
188 while( (sock = SDLNet_UDP_Open(port)) == NULL )
189 port++;
190 return sock;
191 }
192}
193
194void I_CloseSocket(UDP_SOCKET sock)
195{
196 SDLNet_UDP_Close(sock);
197}
198
199UDP_CHANNEL I_RegisterPlayer(IPaddress *ipaddr)
200{
201 static int freechannel;
202 return(SDLNet_UDP_Bind(udp_socket, freechannel++, ipaddr));
203}
204
205void I_UnRegisterPlayer(UDP_CHANNEL channel)
206{
207 SDLNet_UDP_Unbind(udp_socket, channel);
208}
209
210/*
211 * ChecksumPacket
212 *
213 * Returns the checksum of a given network packet
214 */
215static byte ChecksumPacket(const packet_header_t* buffer, size_t len)
216{
217 const byte* p = (const void*)buffer;
218 byte sum = 0;
219
220 if (len==0)
221 return 0;
222
223 while (p++, --len)
224 sum += *p;
225
226 return sum;
227}
228
229size_t I_GetPacket(packet_header_t* buffer, size_t buflen)
230{
231 int checksum;
232 size_t len;
233 int status;
234
235 status = SDLNet_UDP_Recv(udp_socket, udp_packet);
236 len = udp_packet->len;
237 if (buflen<len)
238 len=buflen;
239 if ( (status!=0) && (len>0) )
240 memcpy(buffer, udp_packet->data, len);
241 sentfrom=udp_packet->channel;
242#ifndef SDL_NET_UDP_PACKET_SRC
243 sentfrom_addr=udp_packet->address;
244#else
245 sentfrom_addr=udp_packet->src; /* cph - allow for old SDL_net library */
246#endif
247 checksum=buffer->checksum;
248 buffer->checksum=0;
249 if ( (status!=0) && (len>0)) {
250 byte psum = ChecksumPacket(buffer, udp_packet->len);
251/* fprintf(stderr, "recvlen = %u, stolen = %u, csum = %u, psum = %u\n",
252 udp_packet->len, len, checksum, psum); */
253 if (psum == checksum) return len;
254 }
255 return 0;
256}
257
258void I_SendPacket(packet_header_t* packet, size_t len)
259{
260 packet->checksum = ChecksumPacket(packet, len);
261 memcpy(udp_packet->data, packet, udp_packet->len = len);
262 SDLNet_UDP_Send(udp_socket, 0, udp_packet);
263}
264
265void I_SendPacketTo(packet_header_t* packet, size_t len, UDP_CHANNEL *to)
266{
267 packet->checksum = ChecksumPacket(packet, len);
268 memcpy(udp_packet->data, packet, udp_packet->len = len);
269 SDLNet_UDP_Send(udp_socket, *to, udp_packet);
270}
271
272void I_PrintAddress(FILE* fp, UDP_CHANNEL *addr)
273{
274/*
275 char *addy;
276 Uint16 port;
277 IPaddress *address;
278
279 address = SDLNet_UDP_GetPeerAddress(udp_socket, player);
280
281//FIXME: if it cant resolv it may freeze up
282 addy = SDLNet_ResolveIP(address);
283 port = address->port;
284
285 if(addy != NULL)
286 fprintf(fp, "%s:%d", addy, port);
287 else
288 fprintf(fp, "Error");
289*/
290}
291
292#endif /* HAVE_NET */