1 /*
2  *  Copyright 2006  Serge van den Boom <svdb@stack.nl>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (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 
19 #define PORT_WANT_ERRNO
20 #include "port.h"
21 
22 #define NETCONNECTION_INTERNAL
23 #include "netplay.h"
24 #include "packethandlers.h"
25 
26 #include "netinput.h"
27 #include "netmisc.h"
28 #include "packetsenders.h"
29 #include "proto/npconfirm.h"
30 #include "proto/ready.h"
31 #include "proto/reset.h"
32 #include "libs/log.h"
33 
34 #include "../../controls.h"
35 		// for BATTLE_INPUT_STATE
36 #include "../../init.h"
37 		// for NUM_PLAYERS
38 #include "../../globdata.h"
39 		// for GLOBAL
40 #include "../melee.h"
41 		// for various update functions.
42 #include "../meleeship.h"
43 		// for MeleeShip
44 #include "../pickmele.h"
45 		// for various update functions.
46 #include "libs/mathlib.h"
47 		// for TFB_SeedRandom
48 
49 #include <errno.h>
50 
51 
52 static bool
testNetState(bool condition,PacketType type)53 testNetState(bool condition, PacketType type) {
54 	if (!condition) {
55 		log_add(log_Error, "Packet of type '%s' received from wrong "
56 				"state.", packetTypeData[type].name);
57 		errno = EBADMSG;
58 	}
59 	return condition;
60 }
61 
62 static int
versionCompare(int major1,int minor1,int patch1,int major2,int minor2,int patch2)63 versionCompare(int major1, int minor1, int patch1,
64 		int major2, int minor2, int patch2) {
65 	if (major1 < major2)
66 		return -1;
67 	if (major1 > major2)
68 		return 1;
69 
70 	if (minor1 < minor2)
71 		return -1;
72 	if (minor1 > minor2)
73 		return 1;
74 
75 	if (patch1 < patch2)
76 		return -1;
77 	if (patch1 > patch2)
78 		return 1;
79 
80 	return 0;
81 }
82 
83 int
PacketHandler_Init(NetConnection * conn,const Packet_Init * packet)84 PacketHandler_Init(NetConnection *conn, const Packet_Init *packet) {
85 	if (conn->stateFlags.reset.localReset)
86 		return 0;
87 	if (conn->stateFlags.reset.remoteReset) {
88 		errno = EBADMSG;
89 		return -1;
90 	}
91 
92 	if (!testNetState(conn->state == NetState_init &&
93 			!conn->stateFlags.ready.remoteReady, PACKET_INIT))
94 		return -1;  // errno is set
95 
96 	if (packet->protoVersion.major != NETPLAY_PROTOCOL_VERSION_MAJOR ||
97 			packet->protoVersion.minor != NETPLAY_PROTOCOL_VERSION_MINOR) {
98 		sendAbort (conn, AbortReason_versionMismatch);
99 		abortFeedback(conn, AbortReason_versionMismatch);
100 		log_add(log_Error, "Protocol version %d.%d not supported.",
101 				packet->protoVersion.major, packet->protoVersion.minor);
102 		errno = ENOSYS;
103 		return -1;
104 	}
105 
106 	if (versionCompare(packet->uqmVersion.major, packet->uqmVersion.minor,
107 			packet->uqmVersion.patch, NETPLAY_MIN_UQM_VERSION_MAJOR,
108 			NETPLAY_MIN_UQM_VERSION_MINOR, NETPLAY_MIN_UQM_VERSION_PATCH)
109 			< 0) {
110 		sendAbort (conn, AbortReason_versionMismatch);
111 		abortFeedback(conn, AbortReason_versionMismatch);
112 		log_add(log_Error, "Remote side is running a version of UQM that "
113 				"is too old (%d.%d.%d; %d.%d.%d is required).",
114 				packet->uqmVersion.major, packet->uqmVersion.minor,
115 				packet->uqmVersion.patch, NETPLAY_MIN_UQM_VERSION_MAJOR,
116 				NETPLAY_MIN_UQM_VERSION_MINOR, NETPLAY_MIN_UQM_VERSION_PATCH);
117 		errno = ENOSYS;
118 		return -1;
119 	}
120 
121 	Netplay_remoteReady(conn);
122 
123 	return 0;
124 }
125 
126 int
PacketHandler_Ping(NetConnection * conn,const Packet_Ping * packet)127 PacketHandler_Ping(NetConnection *conn, const Packet_Ping *packet) {
128 	if (!testNetState(conn->state > NetState_init, PACKET_PING))
129 		return -1;  // errno is set
130 
131 	sendAck(conn, packet->id);
132 	return 0;
133 }
134 
135 int
PacketHandler_Ack(NetConnection * conn,const Packet_Ack * packet)136 PacketHandler_Ack(NetConnection *conn, const Packet_Ack *packet) {
137 	if (!testNetState(conn->state > NetState_init, PACKET_ACK))
138 		return -1;  // errno is set
139 
140 	(void) conn;
141 	(void) packet;
142 	return 0;
143 }
144 
145 // Convert the side indication relative to a remote party to
146 // a local player number.
147 static inline int
localSide(NetConnection * conn,NetplaySide side)148 localSide(NetConnection *conn, NetplaySide side) {
149 	if (side == NetplaySide_local) {
150 		// "local" relative to the remote party.
151 		return conn->player;
152 	}
153 
154 	return 1 - conn->player;
155 }
156 
157 int
PacketHandler_Ready(NetConnection * conn,const Packet_Ready * packet)158 PacketHandler_Ready(NetConnection *conn, const Packet_Ready *packet) {
159 	if (conn->stateFlags.reset.localReset)
160 		return 0;
161 	if (conn->stateFlags.reset.remoteReset) {
162 		errno = EBADMSG;
163 		return -1;
164 	}
165 
166 	if (!testNetState(readyFlagsMeaningful(conn->state) &&
167 			!conn->stateFlags.ready.remoteReady, PACKET_READY))
168 		return -1;  // errno is set
169 
170 	Netplay_remoteReady(conn);
171 
172 	(void) packet;
173 			// Its contents is not interesting.
174 
175 	return 0;
176 }
177 
178 int
PacketHandler_Fleet(NetConnection * conn,const Packet_Fleet * packet)179 PacketHandler_Fleet(NetConnection *conn, const Packet_Fleet *packet) {
180 	uint16 numShips = ntoh16(packet->numShips);
181 	size_t i;
182 	size_t len;
183 	int player;
184 	BattleStateData *battleStateData;
185 
186 	if (conn->stateFlags.reset.localReset)
187 		return 0;
188 	if (conn->stateFlags.reset.remoteReset) {
189 		errno = EBADMSG;
190 		return -1;
191 	}
192 
193 	if (!testNetState(conn->state == NetState_inSetup, PACKET_FLEET))
194 		return -1;  // errno is set
195 
196 	player = localSide(conn, (NetplaySide) packet->side);
197 
198 	len = packetLength((const Packet *) packet);
199 	if (sizeof packet + numShips * sizeof(packet->ships[0]) > len) {
200 		// There is not enough room in the packet to contain all
201 		// the ships it says it contains.
202 		log_add(log_Warning, "Invalid fleet size. Specified size is %d, "
203 				"actual size = %d",
204 				numShips, (int) ((len - sizeof packet) / sizeof(packet->ships[0])));
205 		errno = EBADMSG;
206 		return -1;
207 	}
208 
209 	battleStateData = (BattleStateData *) NetConnection_getStateData(conn);
210 
211 	if (conn->stateFlags.handshake.localOk) {
212 		Netplay_cancelConfirmation(conn);
213 		confirmationCancelled(battleStateData->meleeState, conn->player);
214 	}
215 
216 	for (i = 0; i < numShips; i++) {
217 		MeleeShip ship = (MeleeShip) packet->ships[i].ship;
218 		FleetShipIndex index = (FleetShipIndex) packet->ships[i].index;
219 
220 		if (!MeleeShip_valid(ship)) {
221 			log_add (log_Warning, "Invalid ship type number %d (max = %d).\n",
222 					ship, NUM_MELEE_SHIPS - 1);
223 			errno = EBADMSG;
224 			return -1;
225 		}
226 
227 		if (index >= MELEE_FLEET_SIZE)
228 		{
229 			log_add (log_Warning, "Invalid ship position number %d "
230 					"(max = %d).\n", index, MELEE_FLEET_SIZE - 1);
231 			errno = EBADMSG;
232 			return -1;
233 		}
234 
235 		Melee_RemoteChange_ship (battleStateData->meleeState, conn,
236 				player, index, ship);
237 	}
238 
239 	// Padding data may follow; it is ignored.
240 	return 0;
241 }
242 
243 int
PacketHandler_TeamName(NetConnection * conn,const Packet_TeamName * packet)244 PacketHandler_TeamName(NetConnection *conn, const Packet_TeamName *packet) {
245 	size_t nameLen;
246 	int side;
247 	BattleStateData *battleStateData;
248 
249 	if (conn->stateFlags.reset.localReset)
250 		return 0;
251 	if (conn->stateFlags.reset.remoteReset) {
252 		errno = EBADMSG;
253 		return -1;
254 	}
255 
256 	if (!testNetState(conn->state == NetState_inSetup, PACKET_FLEET))
257 		return -1;  // errno is set
258 
259 	battleStateData = (BattleStateData *) NetConnection_getStateData(conn);
260 
261 	if (conn->stateFlags.handshake.localOk) {
262 		Netplay_cancelConfirmation(conn);
263 		confirmationCancelled(battleStateData->meleeState, conn->player);
264 	}
265 
266 	side = localSide(conn, (NetplaySide) packet->side);
267 	nameLen = packetLength((const Packet *) packet)
268 			- sizeof (Packet_TeamName) - 1;
269 			// The -1 is for not counting the terminating '\0'.
270 
271 	{
272 		char buf[MAX_TEAM_CHARS + 1];
273 
274 		if (nameLen > MAX_TEAM_CHARS)
275 			nameLen = MAX_TEAM_CHARS;
276 		memcpy (buf, (const char *) packet->name, nameLen);
277 		buf[nameLen] = '\0';
278 
279 		Melee_RemoteChange_teamName(battleStateData->meleeState, conn,
280 				side, buf);
281 	}
282 
283 	// Padding data may follow; it is ignored.
284 	return 0;
285 }
286 
287 static void
handshakeComplete(NetConnection * conn)288 handshakeComplete(NetConnection *conn) {
289 	assert(!conn->stateFlags.handshake.localOk);
290 	assert(!conn->stateFlags.handshake.remoteOk);
291 	assert(!conn->stateFlags.handshake.canceling);
292 
293 	assert(conn->state == NetState_inSetup);
294 	NetConnection_setState(conn, NetState_preBattle);
295 }
296 
297 int
PacketHandler_Handshake0(NetConnection * conn,const Packet_Handshake0 * packet)298 PacketHandler_Handshake0(NetConnection *conn,
299 		const Packet_Handshake0 *packet) {
300 	if (conn->stateFlags.reset.localReset)
301 		return 0;
302 	if (conn->stateFlags.reset.remoteReset) {
303 		errno = EBADMSG;
304 		return -1;
305 	}
306 
307 	if (!testNetState(handshakeMeaningful(conn->state)
308 			&& !conn->stateFlags.handshake.remoteOk, PACKET_HANDSHAKE0))
309 		return -1;  // errno is set
310 
311 	conn->stateFlags.handshake.remoteOk = true;
312 	if (conn->stateFlags.handshake.localOk &&
313 			!conn->stateFlags.handshake.canceling)
314 		sendHandshake1(conn);
315 
316 	(void) packet;
317 			// Its contents is not interesting.
318 
319 	return 0;
320 }
321 
322 int
PacketHandler_Handshake1(NetConnection * conn,const Packet_Handshake1 * packet)323 PacketHandler_Handshake1(NetConnection *conn,
324 		const Packet_Handshake1 *packet) {
325 	if (conn->stateFlags.reset.localReset)
326 		return 0;
327 	if (conn->stateFlags.reset.remoteReset) {
328 		errno = EBADMSG;
329 		return -1;
330 	}
331 
332 	if (!testNetState(handshakeMeaningful(conn->state) &&
333 			(conn->stateFlags.handshake.localOk ||
334 			conn->stateFlags.handshake.canceling), PACKET_HANDSHAKE1))
335 		return -1;  // errno is set
336 
337 	if (conn->stateFlags.handshake.canceling) {
338 		conn->stateFlags.handshake.remoteOk = true;
339 	} else {
340 		bool remoteWasOk = conn->stateFlags.handshake.remoteOk;
341 
342 		conn->stateFlags.handshake.localOk = false;
343 		conn->stateFlags.handshake.remoteOk = false;
344 
345 		if (!remoteWasOk) {
346 			// Received Handshake1 without prior Handshake0.
347 			// A Handshake0 is implied, but we still need to confirm
348 			// it with a Handshake1.
349 			sendHandshake1(conn);
350 		}
351 
352 		handshakeComplete(conn);
353 	}
354 
355 	(void) packet;
356 			// Its contents is not interesting.
357 
358 	return 0;
359 }
360 
361 int
PacketHandler_HandshakeCancel(NetConnection * conn,const Packet_HandshakeCancel * packet)362 PacketHandler_HandshakeCancel(NetConnection *conn,
363 		const Packet_HandshakeCancel *packet) {
364 	if (conn->stateFlags.reset.localReset)
365 		return 0;
366 	if (conn->stateFlags.reset.remoteReset) {
367 		errno = EBADMSG;
368 		return -1;
369 	}
370 
371 	if (!testNetState(handshakeMeaningful(conn->state)
372 			&& conn->stateFlags.handshake.remoteOk, PACKET_HANDSHAKECANCEL))
373 		return -1;  // errno is set
374 
375 	conn->stateFlags.handshake.remoteOk = false;
376 	sendHandshakeCancelAck(conn);
377 
378 	(void) packet;
379 			// Its contents is not interesting.
380 
381 	return 0;
382 }
383 
384 int
PacketHandler_HandshakeCancelAck(NetConnection * conn,const Packet_HandshakeCancelAck * packet)385 PacketHandler_HandshakeCancelAck(NetConnection *conn,
386 		const Packet_HandshakeCancelAck *packet) {
387 	if (conn->stateFlags.reset.localReset)
388 		return 0;
389 	if (conn->stateFlags.reset.remoteReset) {
390 		errno = EBADMSG;
391 		return -1;
392 	}
393 
394 	if (!testNetState(handshakeMeaningful(conn->state)
395 			&& conn->stateFlags.handshake.canceling,
396 			PACKET_HANDSHAKECANCELACK))
397 		return -1;  // errno is set
398 
399 	conn->stateFlags.handshake.canceling = false;
400 	if (conn->stateFlags.handshake.localOk) {
401 		if (conn->stateFlags.handshake.remoteOk) {
402 			sendHandshake1(conn);
403 		} else
404 			sendHandshake0(conn);
405 	}
406 
407 	(void) packet;
408 			// Its contents is not interesting.
409 
410 	return 0;
411 }
412 
413 int
PacketHandler_SeedRandom(NetConnection * conn,const Packet_SeedRandom * packet)414 PacketHandler_SeedRandom(NetConnection *conn,
415 		const Packet_SeedRandom *packet) {
416 	BattleStateData *battleStateData;
417 
418 	if (conn->stateFlags.reset.localReset)
419 		return 0;
420 	if (conn->stateFlags.reset.remoteReset) {
421 		errno = EBADMSG;
422 		return -1;
423 	}
424 
425 	if (!testNetState(conn->state == NetState_preBattle &&
426 			!conn->stateFlags.discriminant, PACKET_SEEDRANDOM))
427 		return -1;  // errno is set
428 
429 	battleStateData = (BattleStateData *) NetConnection_getStateData(conn);
430 	updateRandomSeed (battleStateData->meleeState, conn->player,
431 			ntoh32(packet->seed));
432 
433 	conn->stateFlags.agreement.randomSeed = true;
434 	return 0;
435 }
436 
437 int
PacketHandler_InputDelay(NetConnection * conn,const Packet_InputDelay * packet)438 PacketHandler_InputDelay(NetConnection *conn,
439 		const Packet_InputDelay *packet) {
440 	BattleStateData *battleStateData;
441 	uint32 delay;
442 
443 	if (conn->stateFlags.reset.localReset)
444 		return 0;
445 	if (conn->stateFlags.reset.remoteReset) {
446 		errno = EBADMSG;
447 		return -1;
448 	}
449 
450 	if (!testNetState(conn->state == NetState_preBattle, PACKET_INPUTDELAY))
451 		return -1;  // errno is set
452 
453 	battleStateData = (BattleStateData *) NetConnection_getStateData(conn);
454 	delay = ntoh32(packet->delay);
455 	if (delay > BATTLE_FRAME_RATE) {
456 		log_add(log_Error, "NETPLAY: [%d]     Received absurdly large "
457 				"input delay value (%d).", conn->player, delay);
458 		return -1;
459 	}
460 	conn->stateFlags.inputDelay = delay;
461 
462 	return 0;
463 }
464 
465 int
PacketHandler_SelectShip(NetConnection * conn,const Packet_SelectShip * packet)466 PacketHandler_SelectShip(NetConnection *conn,
467 		const Packet_SelectShip *packet) {
468 	bool updateResult;
469 	BattleStateData *battleStateData;
470 
471 	if (conn->stateFlags.reset.localReset)
472 		return 0;
473 	if (conn->stateFlags.reset.remoteReset) {
474 		errno = EBADMSG;
475 		return -1;
476 	}
477 
478 	if (!testNetState(conn->state == NetState_selectShip, PACKET_SELECTSHIP))
479 		return -1;  // errno is set
480 
481 	battleStateData = (BattleStateData *) NetConnection_getStateData(conn);
482 	updateResult = updateMeleeSelection(battleStateData->getMeleeState,
483 			conn->player, ntoh16(packet->ship));
484 	if (!updateResult)
485 	{
486 		errno = EBADMSG;
487 		return -1;
488 	}
489 
490 	return 0;
491 }
492 
493 int
PacketHandler_BattleInput(NetConnection * conn,const Packet_BattleInput * packet)494 PacketHandler_BattleInput(NetConnection *conn,
495 		const Packet_BattleInput *packet) {
496 	BATTLE_INPUT_STATE input;
497 	BattleInputBuffer *bib;
498 
499 	if (conn->stateFlags.reset.localReset)
500 		return 0;
501 	if (conn->stateFlags.reset.remoteReset) {
502 		errno = EBADMSG;
503 		return -1;
504 	}
505 
506 	if (!testNetState(conn->state == NetState_inBattle ||
507 			conn->state == NetState_endingBattle ||
508 			conn->state == NetState_endingBattle2, PACKET_BATTLEINPUT))
509 		return -1;  // errno is set
510 
511 	input = (BATTLE_INPUT_STATE) packet->state;
512 	bib = getBattleInputBuffer(conn->player);
513 	if (!BattleInputBuffer_push(bib, input)) {
514 		// errno is set
515 		return -1;
516 	}
517 
518 	return 0;
519 }
520 
521 int
PacketHandler_FrameCount(NetConnection * conn,const Packet_FrameCount * packet)522 PacketHandler_FrameCount(NetConnection *conn,
523 		const Packet_FrameCount *packet) {
524 	BattleStateData *battleStateData;
525 	BattleFrameCounter frameCount;
526 
527 	if (conn->stateFlags.reset.localReset)
528 		return 0;
529 	if (conn->stateFlags.reset.remoteReset) {
530 		errno = EBADMSG;
531 		return -1;
532 	}
533 
534 	if (!testNetState(conn->state == NetState_endingBattle,
535 			PACKET_FRAMECOUNT))
536 		return -1;  // errno is set
537 
538 	frameCount = (BattleFrameCounter) ntoh32(packet->frameCount);
539 #ifdef NETPLAY_DEBUG
540 	log_add(log_Debug, "NETPLAY: [%d] <== Received battleFrameCount %u.",
541 			conn->player, (unsigned int) frameCount);
542 #endif
543 
544 	battleStateData = (BattleStateData *) NetConnection_getStateData(conn);
545 	if (frameCount > battleStateData->endFrameCount)
546 		battleStateData->endFrameCount = frameCount;
547 	Netplay_remoteReady(conn);
548 
549 	return 0;
550 }
551 
552 int
PacketHandler_Checksum(NetConnection * conn,const Packet_Checksum * packet)553 PacketHandler_Checksum(NetConnection *conn, const Packet_Checksum *packet) {
554 #ifdef NETPLAY_CHECKSUM
555 	uint32 frameNr;
556 	uint32 checksum;
557 	size_t delay;
558 	size_t interval;
559 #endif
560 
561 	if (conn->stateFlags.reset.localReset)
562 		return 0;
563 	if (conn->stateFlags.reset.remoteReset) {
564 		errno = EBADMSG;
565 		return -1;
566 	}
567 
568 	if (!testNetState(NetState_battleActive(conn->state), PACKET_CHECKSUM))
569 		return -1;  // errno is set
570 
571 #ifdef NETPLAY_CHECKSUM
572 	frameNr = ntoh32(packet->frameNr);
573 	checksum = ntoh32(packet->checksum);
574 	interval = NetConnection_getChecksumInterval(conn);
575 	delay = getBattleInputDelay();
576 
577 	if (frameNr % interval != 0) {
578 		log_add(log_Warning, "NETPLAY: [%d] <== Received checksum "
579 				"for frame %u, while we only expect checksums on frames "
580 				"divisable by %u -- discarding.", conn->player,
581 				(unsigned int) frameNr, (unsigned int) interval);
582 		return 0;
583 				// No need to close the connection; checksums are not
584 				// essential.
585 	}
586 
587 	// The checksum is sent at the beginning of a frame.
588 	// If we're in frame n and have sent our input already,
589 	// the remote side has got enough input to progress delay + 1 frames from
590 	// frame n. The next frame is then n + delay + 1, for which we can
591 	// receive a checksum.
592 	if (frameNr > battleFrameCount + delay + 1) {
593 		log_add(log_Warning, "NETPLAY: [%d] <== Received checksum "
594 				"for a frame too far in the future (frame %u, current "
595 				"is %u, input delay is %u) -- discarding.", conn->player,
596 				(unsigned int) frameNr, (unsigned int) battleFrameCount, (unsigned int) delay);
597 		return 0;
598 				// No need to close the connection; checksums are not
599 				// essential.
600 	}
601 
602 	// We can progress delay more frames after the last frame for which we
603 	// received input. If we call that frame n, we can complete frames
604 	// n through n + delay - 1. While we are waiting for the next input,
605 	// in frame n + delay,  we will first receive the checksum that the
606 	// remote side sent at the start of frame n + 1.
607 	// In this situation frameNr is n + 1, and battleFrameCount is
608 	// n + delay.
609 	if (frameNr + delay < battleFrameCount) {
610 		log_add(log_Warning, "NETPLAY: [%d] <== Received checksum "
611 				"for a frame too far in the past (frame %u, current "
612 				"is %u, input delay is %u) -- discarding.", conn->player,
613 				(unsigned int) frameNr, (unsigned int) battleFrameCount, (unsigned int) delay);
614 		return 0;
615 				// No need to close the connection; checksums are not
616 				// essential.
617 	}
618 
619 	addRemoteChecksum(conn, frameNr, checksum);
620 #endif
621 
622 #ifndef NETPLAY_CHECKSUM
623 	(void) packet;
624 #endif
625 	return 0;
626 }
627 
628 int
PacketHandler_Abort(NetConnection * conn,const Packet_Abort * packet)629 PacketHandler_Abort(NetConnection *conn, const Packet_Abort *packet) {
630 	abortFeedback(conn, packet->reason);
631 
632 	return -1;
633 			// Close connection.
634 }
635 
636 int
PacketHandler_Reset(NetConnection * conn,const Packet_Reset * packet)637 PacketHandler_Reset(NetConnection *conn, const Packet_Reset *packet) {
638 	NetplayResetReason reason;
639 
640 	if (!testNetState(!conn->stateFlags.reset.remoteReset, PACKET_RESET))
641 		return -1;  // errno is set
642 
643 	reason = ntoh16(packet->reason);
644 
645 	Netplay_remoteReset(conn, reason);
646 	return 0;
647 }
648 
649 
650