diff options
Diffstat (limited to 'network/core')
-rw-r--r-- | network/core/config.h | 49 | ||||
-rw-r--r-- | network/core/game.h | 47 | ||||
-rw-r--r-- | network/core/os_abstraction.h | 181 | ||||
-rw-r--r-- | network/core/packet.c | 216 | ||||
-rw-r--r-- | network/core/packet.h | 67 | ||||
-rw-r--r-- | network/core/tcp.c | 227 | ||||
-rw-r--r-- | network/core/tcp.h | 60 | ||||
-rw-r--r-- | network/core/udp.c | 277 | ||||
-rw-r--r-- | network/core/udp.h | 62 |
9 files changed, 0 insertions, 1186 deletions
diff --git a/network/core/config.h b/network/core/config.h deleted file mode 100644 index 0b80800f0..000000000 --- a/network/core/config.h +++ /dev/null @@ -1,49 +0,0 @@ -/* $Id$ */ - -#ifndef NETWORK_CORE_CONFIG_H -#define NETWORK_CORE_CONFIG_H - -#ifdef ENABLE_NETWORK - -/** DNS hostname of the masterserver */ -#define NETWORK_MASTER_SERVER_HOST "master.openttd.org" -/** Message sent to the masterserver to 'identify' this client as OpenTTD */ -#define NETWORK_MASTER_SERVER_WELCOME_MESSAGE "OpenTTDRegister" - -enum { - NETWORK_MASTER_SERVER_PORT = 3978, ///< The default port of the master server (UDP) - NETWORK_DEFAULT_PORT = 3979, ///< The default port of the game server (TCP & UDP) - - SEND_MTU = 1460, ///< Number of bytes we can pack in a single packet - - NETWORK_GAME_INFO_VERSION = 4, ///< What version of game-info do we use? - NETWORK_COMPANY_INFO_VERSION = 4, ///< What version of company info is this? - NETWORK_MASTER_SERVER_VERSION = 1, ///< What version of master-server-protocol do we use? - - NETWORK_NAME_LENGTH = 80, ///< The maximum length of the server name and map name, in bytes including '\0' - NETWORK_HOSTNAME_LENGTH = 80, ///< The maximum length of the host name, in bytes including '\0' - NETWORK_REVISION_LENGTH = 15, ///< The maximum length of the revision, in bytes including '\0' - NETWORK_PASSWORD_LENGTH = 20, ///< The maximum length of the password, in bytes including '\0' - NETWORK_PLAYERS_LENGTH = 200, ///< The maximum length for the list of players that controls a company, in bytes including '\0' - NETWORK_CLIENT_NAME_LENGTH = 25, ///< The maximum length of a player, in bytes including '\0' - NETWORK_RCONCOMMAND_LENGTH = 500, ///< The maximum length of a rconsole command, in bytes including '\0' - - NETWORK_GRF_NAME_LENGTH = 80, ///< Maximum length of the name of a GRF - /** - * Maximum number of GRFs that can be sent. - * This value is related to number of handles (files) OpenTTD can open. - * This is currently 64 and about 10 are currently used when OpenTTD loads - * without any NewGRFs. Therefore one can only load about 55 NewGRFs, so - * this is not a limit, but rather a way to easily check whether the limit - * imposed by the handle count is reached. Secondly it isn't possible to - * send much more GRF IDs + MD5sums in the PACKET_UDP_SERVER_RESPONSE, due - * to the limited size of UDP packets. - */ - NETWORK_MAX_GRF_COUNT = 55, - - NETWORK_NUM_LANGUAGES = 4, ///< Number of known languages (to the network protocol) + 1 for 'any'. -}; - -#endif /* ENABLE_NETWORK */ - -#endif /* NETWORK_CORE_CONFIG_H */ diff --git a/network/core/game.h b/network/core/game.h deleted file mode 100644 index 71268f7d2..000000000 --- a/network/core/game.h +++ /dev/null @@ -1,47 +0,0 @@ -/* $Id$ */ - -#ifndef NETWORK_CORE_GAME_H -#define NETWORK_CORE_GAME_H - -#ifdef ENABLE_NETWORK - -/** - * @file game.h Information about a game that is sent between a - * game server, game client and masterserver. - */ - -/** - * This is the struct used by both client and server - * some fields will be empty on the client (like game_password) by default - * and only filled with data a player enters. - */ -typedef struct NetworkGameInfo { - byte game_info_version; ///< Version of the game info - char server_name[NETWORK_NAME_LENGTH]; ///< Server name - char hostname[NETWORK_HOSTNAME_LENGTH]; ///< Hostname of the server (if any) - char server_revision[NETWORK_REVISION_LENGTH]; ///< The version number the server is using (e.g.: 'r304' or 0.5.0) - bool version_compatible; ///< Can we connect to this server or not? (based on server_revision) - bool compatible; ///< Can we connect to this server or not? (based on server_revision _and_ grf_match - byte server_lang; ///< Language of the server (we should make a nice table for this) - byte use_password; ///< Is set to != 0 if it uses a password - char server_password[NETWORK_PASSWORD_LENGTH]; ///< On the server: the game password, on the client: != "" if server has password - byte clients_max; ///< Max clients allowed on server - byte clients_on; ///< Current count of clients on server - byte companies_max; ///< Max companies allowed on server - byte companies_on; ///< How many started companies do we have - byte spectators_max; ///< Max spectators allowed on server - byte spectators_on; ///< How many spectators do we have? - Date game_date; ///< Current date - Date start_date; ///< When the game started - char map_name[NETWORK_NAME_LENGTH]; ///< Map which is played ["random" for a randomized map] - uint16 map_width; ///< Map width - uint16 map_height; ///< Map height - byte map_set; ///< Graphical set - bool dedicated; ///< Is this a dedicated server? - char rcon_password[NETWORK_PASSWORD_LENGTH]; ///< RCon password for the server. "" if rcon is disabled - struct GRFConfig *grfconfig; ///< List of NewGRF files used -} NetworkGameInfo; - -#endif /* ENABLE_NETWORK */ - -#endif /* NETWORK_CORE_GAME_H */ diff --git a/network/core/os_abstraction.h b/network/core/os_abstraction.h deleted file mode 100644 index c7df16a93..000000000 --- a/network/core/os_abstraction.h +++ /dev/null @@ -1,181 +0,0 @@ -/* $Id$ */ - -#ifndef NETWORK_CORE_OS_ABSTRACTION_H -#define NETWORK_CORE_OS_ABSTRACTION_H - -/** - * @file os_abstraction.h Network stuff has many things that needs to be - * included and/or implemented by default. - * All those things are in this file. - */ - -/* Include standard stuff per OS */ - -#ifdef ENABLE_NETWORK - -/* Windows stuff */ -#if defined(WIN32) || defined(WIN64) -#include <winsock2.h> -#include <ws2tcpip.h> -#include <windows.h> - -#if !(defined(__MINGW32__) || defined(__CYGWIN__)) - /* Windows has some different names for some types */ - typedef SSIZE_T ssize_t; - typedef int socklen_t; -#endif - -#define GET_LAST_ERROR() WSAGetLastError() -#define EWOULDBLOCK WSAEWOULDBLOCK -/* Windows has some different names for some types */ -typedef unsigned long in_addr_t; -#endif /* WIN32 */ - -/* UNIX stuff */ -#if defined(UNIX) -# define SOCKET int -# define INVALID_SOCKET -1 -# if !defined(__MORPHOS__) && !defined(__AMIGA__) -# define ioctlsocket ioctl -# if !defined(BEOS_NET_SERVER) -# define closesocket close -# endif -# define GET_LAST_ERROR() (errno) -# endif -/* Need this for FIONREAD on solaris */ -# define BSD_COMP - -/* Includes needed for UNIX-like systems */ -# include <unistd.h> -# include <sys/ioctl.h> -# if defined(__BEOS__) && defined(BEOS_NET_SERVER) -# include <be/net/socket.h> -# include <be/kernel/OS.h> // snooze() -# include <be/net/netdb.h> - typedef unsigned long in_addr_t; -# define INADDR_NONE INADDR_BROADCAST -# else -# include <sys/socket.h> -# include <netinet/in.h> -# include <netinet/tcp.h> -# include <arpa/inet.h> -# include <net/if.h> -/* According to glibc/NEWS, <ifaddrs.h> appeared in glibc-2.3. */ -# if !defined(__sgi__) && !defined(SUNOS) && !defined(__MORPHOS__) && !defined(__BEOS__) && !defined(__INNOTEK_LIBC__) \ - && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__) -/* If for any reason ifaddrs.h does not exist on your system, comment out - * the following two lines and an alternative way will be used to fetch - * the list of IPs from the system. */ -# include <ifaddrs.h> -# define HAVE_GETIFADDRS -# endif -# if defined(SUNOS) || defined(__MORPHOS__) || defined(__BEOS__) -# define INADDR_NONE 0xffffffff -# endif -# if defined(__BEOS__) && !defined(BEOS_NET_SERVER) - /* needed on Zeta */ -# include <sys/sockio.h> -# endif -# endif /* BEOS_NET_SERVER */ - -# if !defined(__BEOS__) && defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 1) - typedef uint32_t in_addr_t; -# endif - -# include <errno.h> -# include <sys/time.h> -# include <netdb.h> -#endif // UNIX - -#ifdef __BEOS__ - typedef int socklen_t; -#endif - -/* OS/2 stuff */ -#if defined(__OS2__) -# define SOCKET int -# define INVALID_SOCKET -1 -# define ioctlsocket ioctl -# define closesocket close -# define GET_LAST_ERROR() (sock_errno()) - -/* Includes needed for OS/2 systems */ -# include <types.h> -# include <unistd.h> -# include <sys/ioctl.h> -# include <sys/socket.h> -# include <netinet/in.h> -# include <netinet/tcp.h> -# include <arpa/inet.h> -# include <net/if.h> -# include <errno.h> -# include <sys/time.h> -# include <netdb.h> -# include <nerrno.h> -# define INADDR_NONE 0xffffffff - -typedef int socklen_t; -#if !defined(__INNOTEK_LIBC__) -typedef unsigned long in_addr_t; -#endif /* __INNOTEK_LIBC__ */ -#endif /* OS/2 */ - -/* MorphOS and Amiga stuff */ -#if defined(__MORPHOS__) || defined(__AMIGA__) -# include <exec/types.h> -# include <proto/exec.h> // required for Open/CloseLibrary() -# if defined(__MORPHOS__) -# include <sys/filio.h> // FIO* defines -# include <sys/sockio.h> // SIO* defines -# include <netinet/in.h> -# else /* __AMIGA__ */ -# include <proto/socket.h> -# endif - -/* Make the names compatible */ -# define closesocket(s) CloseSocket(s) -# define GET_LAST_ERROR() Errno() -# define ioctlsocket(s,request,status) IoctlSocket((LONG)s,(ULONG)request,(char*)status) -# define ioctl ioctlsocket - - typedef unsigned int in_addr_t; - typedef long socklen_t; - extern struct Library *SocketBase; - -# ifdef __AMIGA__ - /* for usleep() implementation */ - extern struct Device *TimerBase; - extern struct MsgPort *TimerPort; - extern struct timerequest *TimerRequest; -# endif -#endif // __MORPHOS__ || __AMIGA__ - -static inline bool SetNonBlocking(int d) -{ -#ifdef WIN32 - u_long nonblocking = 1; -#else - int nonblocking = 1; -#endif -#if defined(__BEOS__) && defined(BEOS_NET_SERVER) - return setsockopt(d, SOL_SOCKET, SO_NONBLOCK, &nonblocking, sizeof(nonblocking)) == 0; -#else - return ioctlsocket(d, FIONBIO, &nonblocking) == 0; -#endif -} - -static inline bool SetNoDelay(int d) -{ - /* XXX should this be done at all? */ -#if !defined(BEOS_NET_SERVER) // not implemented on BeOS net_server - int b = 1; - /* The (const char*) cast is needed for windows */ - return setsockopt(d, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)) == 0; -#else - return true; -#endif -} - -#endif /* ENABLE_NETWORK */ - -#endif /* NETWORK_CORE_OS_ABSTRACTION_H */ diff --git a/network/core/packet.c b/network/core/packet.c deleted file mode 100644 index 957bd2ad6..000000000 --- a/network/core/packet.c +++ /dev/null @@ -1,216 +0,0 @@ -/* $Id$ */ - -#ifdef ENABLE_NETWORK - -#include "../../stdafx.h" -#include "../../macros.h" -#include "../../string.h" - -#include "os_abstraction.h" -#include "config.h" -#include "packet.h" - -/** - * @file packet.h Basic functions to create, fill and read packets. - */ - - -/* Do not want to include functions.h and all required headers */ -extern void NORETURN CDECL error(const char *str, ...); - - -/** - * Create a packet for sending - * @param type the of packet - * @return the newly created packet - */ -Packet *NetworkSend_Init(PacketType type) -{ - Packet *packet = malloc(sizeof(Packet)); - /* An error is inplace here, because it simply means we ran out of memory. */ - if (packet == NULL) error("Failed to allocate Packet"); - - /* Skip the size so we can write that in before sending the packet */ - packet->size = sizeof(packet->size); - packet->buffer[packet->size++] = type; - packet->pos = 0; - - return packet; -} - -/** - * Writes the packet size from the raw packet from packet->size - * @param packet the packet to write the size of - */ -void NetworkSend_FillPacketSize(Packet *packet) -{ - packet->buffer[0] = GB(packet->size, 0, 8); - packet->buffer[1] = GB(packet->size, 8, 8); -} - -/** - * The next couple of functions make sure we can send - * uint8, uint16, uint32 and uint64 endian-safe - * over the network. The least significant bytes are - * sent first. - * - * So 0x01234567 would be sent as 67 45 23 01. - */ - -void NetworkSend_uint8(Packet *packet, uint8 data) -{ - assert(packet->size < sizeof(packet->buffer) - sizeof(data)); - packet->buffer[packet->size++] = data; -} - -void NetworkSend_uint16(Packet *packet, uint16 data) -{ - assert(packet->size < sizeof(packet->buffer) - sizeof(data)); - packet->buffer[packet->size++] = GB(data, 0, 8); - packet->buffer[packet->size++] = GB(data, 8, 8); -} - -void NetworkSend_uint32(Packet *packet, uint32 data) -{ - assert(packet->size < sizeof(packet->buffer) - sizeof(data)); - packet->buffer[packet->size++] = GB(data, 0, 8); - packet->buffer[packet->size++] = GB(data, 8, 8); - packet->buffer[packet->size++] = GB(data, 16, 8); - packet->buffer[packet->size++] = GB(data, 24, 8); -} - -void NetworkSend_uint64(Packet *packet, uint64 data) -{ - assert(packet->size < sizeof(packet->buffer) - sizeof(data)); - packet->buffer[packet->size++] = GB(data, 0, 8); - packet->buffer[packet->size++] = GB(data, 8, 8); - packet->buffer[packet->size++] = GB(data, 16, 8); - packet->buffer[packet->size++] = GB(data, 24, 8); - packet->buffer[packet->size++] = GB(data, 32, 8); - packet->buffer[packet->size++] = GB(data, 40, 8); - packet->buffer[packet->size++] = GB(data, 48, 8); - packet->buffer[packet->size++] = GB(data, 56, 8); -} - -/** - * Sends a string over the network. It sends out - * the string + '\0'. No size-byte or something. - */ -void NetworkSend_string(Packet *packet, const char* data) -{ - assert(data != NULL); - assert(packet->size < sizeof(packet->buffer) - strlen(data) - 1); - while ((packet->buffer[packet->size++] = *data++) != '\0') {} -} - - -/** - * Receiving commands - * Again, the next couple of functions are endian-safe - * see the comment before NetworkSend_uint8 for more info. - */ - - -extern uint CloseConnection(NetworkClientState *cs); - -/** Is it safe to read from the packet, i.e. didn't we run over the buffer ? */ -static inline bool CanReadFromPacket(NetworkClientState *cs, Packet *packet, uint bytes_to_read) -{ - /* Don't allow reading from a closed socket */ - if (HasClientQuit(cs)) return false; - - /* Check if variable is within packet-size */ - if (packet->pos + bytes_to_read > packet->size) { - CloseConnection(cs); - return false; - } - - return true; -} - -/** - * Reads the packet size from the raw packet and stores it in the packet->size - * @param packet the packet to read the size of - */ -void NetworkRecv_ReadPacketSize(Packet *packet) -{ - packet->size = (uint16)packet->buffer[0]; - packet->size += (uint16)packet->buffer[1] << 8; -} - -uint8 NetworkRecv_uint8(NetworkClientState *cs, Packet *packet) -{ - uint8 n; - - if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0; - - n = packet->buffer[packet->pos++]; - return n; -} - -uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet) -{ - uint16 n; - - if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0; - - n = (uint16)packet->buffer[packet->pos++]; - n += (uint16)packet->buffer[packet->pos++] << 8; - return n; -} - -uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet) -{ - uint32 n; - - if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0; - - n = (uint32)packet->buffer[packet->pos++]; - n += (uint32)packet->buffer[packet->pos++] << 8; - n += (uint32)packet->buffer[packet->pos++] << 16; - n += (uint32)packet->buffer[packet->pos++] << 24; - return n; -} - -uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet) -{ - uint64 n; - - if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0; - - n = (uint64)packet->buffer[packet->pos++]; - n += (uint64)packet->buffer[packet->pos++] << 8; - n += (uint64)packet->buffer[packet->pos++] << 16; - n += (uint64)packet->buffer[packet->pos++] << 24; - n += (uint64)packet->buffer[packet->pos++] << 32; - n += (uint64)packet->buffer[packet->pos++] << 40; - n += (uint64)packet->buffer[packet->pos++] << 48; - n += (uint64)packet->buffer[packet->pos++] << 56; - return n; -} - -/** Reads a string till it finds a '\0' in the stream */ -void NetworkRecv_string(NetworkClientState *cs, Packet *p, char *buffer, size_t size) -{ - PacketSize pos; - char *bufp = buffer; - - /* Don't allow reading from a closed socket */ - if (HasClientQuit(cs)) return; - - pos = p->pos; - while (--size > 0 && pos < p->size && (*buffer++ = p->buffer[pos++]) != '\0') {} - - if (size == 0 || pos == p->size) { - *buffer = '\0'; - /* If size was sooner to zero then the string in the stream - * skip till the \0, so than packet can be read out correctly for the rest */ - while (pos < p->size && p->buffer[pos] != '\0') pos++; - pos++; - } - p->pos = pos; - - str_validate(bufp); -} - -#endif /* ENABLE_NETWORK */ diff --git a/network/core/packet.h b/network/core/packet.h deleted file mode 100644 index 2510c69a7..000000000 --- a/network/core/packet.h +++ /dev/null @@ -1,67 +0,0 @@ -/* $Id$ */ - -#ifndef NETWORK_CORE_PACKET_H -#define NETWORK_CORE_PACKET_H - -#ifdef ENABLE_NETWORK - -/** - * @file packet.h Basic functions to create, fill and read packets. - */ - -typedef struct NetworkClientState NetworkClientState; - -/** - * Queries the network client state struct to determine whether - * the client has quit. It indirectly also queries whether the - * packet is corrupt as the connection will be closed if it is - * reading beyond the boundary of the received packet. - * @param cs the state to query - * @param true if the connection should be considered dropped - */ -bool HasClientQuit(NetworkClientState *cs); - -typedef uint16 PacketSize; ///< Size of the whole packet. -typedef uint8 PacketType; ///< Identifier for the packet - -/** - * Internal entity of a packet. As everything is sent as a packet, - * all network communication will need to call the functions that - * populate the packet. - * Every packet can be at most SEND_MTU bytes. Overflowing this - * limit will give an assertion when sending (i.e. writing) the - * packet. Reading past the size of the packet when receiving - * will return all 0 values and "" in case of the string. - */ -typedef struct Packet { - /** The next packet. Used for queueing packets before sending. */ - struct Packet *next; - /** The size of the whole packet for received packets. For packets - * that will be sent, the value is filled in just before the - * actual transmission. */ - PacketSize size; - /** The current read/write position in the packet */ - PacketSize pos; - /** The buffer of this packet */ - byte buffer[SEND_MTU]; -} Packet; - - -Packet *NetworkSend_Init(PacketType type); -void NetworkSend_FillPacketSize(Packet *packet); -void NetworkSend_uint8 (Packet *packet, uint8 data); -void NetworkSend_uint16(Packet *packet, uint16 data); -void NetworkSend_uint32(Packet *packet, uint32 data); -void NetworkSend_uint64(Packet *packet, uint64 data); -void NetworkSend_string(Packet *packet, const char* data); - -void NetworkRecv_ReadPacketSize(Packet *packet); -uint8 NetworkRecv_uint8 (NetworkClientState *cs, Packet *packet); -uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet); -uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet); -uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet); -void NetworkRecv_string(NetworkClientState *cs, Packet *packet, char* buffer, size_t size); - -#endif /* ENABLE_NETWORK */ - -#endif /* NETWORK_CORE_PACKET_H */ diff --git a/network/core/tcp.c b/network/core/tcp.c deleted file mode 100644 index 493a97dff..000000000 --- a/network/core/tcp.c +++ /dev/null @@ -1,227 +0,0 @@ -/* $Id$ */ - -#ifdef ENABLE_NETWORK - -#include "../../stdafx.h" -#include "../../debug.h" -#include "../../openttd.h" -#include "../../variables.h" -#include "../../table/strings.h" -#include "../../functions.h" - -#include "os_abstraction.h" -#include "config.h" -#include "packet.h" -#include "../network_data.h" -#include "tcp.h" - -/** - * @file tcp.c Basic functions to receive and send TCP packets. - */ - -/** - * Functions to help NetworkRecv_Packet/NetworkSend_Packet a bit - * A socket can make errors. When that happens this handles what to do. - * For clients: close connection and drop back to main-menu - * For servers: close connection and that is it - * @param cs the client to close the connection of - * @return the new status - */ -NetworkRecvStatus CloseConnection(NetworkClientState *cs) -{ - NetworkCloseClient(cs); - - /* Clients drop back to the main menu */ - if (!_network_server && _networking) { - _switch_mode = SM_MENU; - _networking = false; - _switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION; - - return NETWORK_RECV_STATUS_CONN_LOST; - } - - return NETWORK_RECV_STATUS_OKAY; -} - -/** - * Whether the client has quit or not (used in packet.c) - * @param cs the client to check - * @return true if the client has quit - */ -bool HasClientQuit(NetworkClientState *cs) -{ - return cs->has_quit; -} - -/** - * This function puts the packet in the send-queue and it is send as - * soon as possible. This is the next tick, or maybe one tick later - * if the OS-network-buffer is full) - * @param packet the packet to send - * @param cs the client to send to - */ -void NetworkSend_Packet(Packet *packet, NetworkClientState *cs) -{ - Packet *p; - assert(packet != NULL); - - packet->pos = 0; - packet->next = NULL; - - NetworkSend_FillPacketSize(packet); - - /* Locate last packet buffered for the client */ - p = cs->packet_queue; - if (p == NULL) { - /* No packets yet */ - cs->packet_queue = packet; - } else { - /* Skip to the last packet */ - while (p->next != NULL) p = p->next; - p->next = packet; - } -} - -/** - * Sends all the buffered packets out for this client. It stops when: - * 1) all packets are send (queue is empty) - * 2) the OS reports back that it can not send any more - * data right now (full network-buffer, it happens ;)) - * 3) sending took too long - * @param cs the client to send the packets for - */ -bool NetworkSend_Packets(NetworkClientState *cs) -{ - ssize_t res; - Packet *p; - - /* We can not write to this socket!! */ - if (!cs->writable) return false; - if (cs->socket == INVALID_SOCKET) return false; - - p = cs->packet_queue; - while (p != NULL) { - res = send(cs->socket, p->buffer + p->pos, p->size - p->pos, 0); - if (res == -1) { - int err = GET_LAST_ERROR(); - if (err != EWOULDBLOCK) { - /* Something went wrong.. close client! */ - DEBUG(net, 0, "send failed with error %d", err); - CloseConnection(cs); - return false; - } - return true; - } - if (res == 0) { - /* Client/server has left us :( */ - CloseConnection(cs); - return false; - } - - p->pos += res; - - /* Is this packet sent? */ - if (p->pos == p->size) { - /* Go to the next packet */ - cs->packet_queue = p->next; - free(p); - p = cs->packet_queue; - } else { - return true; - } - } - - return true; -} - -/** - * Receives a packet for the given client - * @param cs the client to (try to) receive a packet for - * @param status the variable to store the status into - * @return the received packet (or NULL when it didn't receive one) - */ -Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status) -{ - ssize_t res; - Packet *p; - - *status = NETWORK_RECV_STATUS_OKAY; - - if (cs->socket == INVALID_SOCKET) return NULL; - - if (cs->packet_recv == NULL) { - cs->packet_recv = malloc(sizeof(Packet)); - if (cs->packet_recv == NULL) error("Failed to allocate packet"); - /* Set pos to zero! */ - cs->packet_recv->pos = 0; - cs->packet_recv->size = 0; // Can be ommited, just for safety reasons - } - - p = cs->packet_recv; - - /* Read packet size */ - if (p->pos < sizeof(PacketSize)) { - while (p->pos < sizeof(PacketSize)) { - /* Read the size of the packet */ - res = recv(cs->socket, p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0); - if (res == -1) { - int err = GET_LAST_ERROR(); - if (err != EWOULDBLOCK) { - /* Something went wrong... (104 is connection reset by peer) */ - if (err != 104) DEBUG(net, 0, "recv failed with error %d", err); - *status = CloseConnection(cs); - return NULL; - } - /* Connection would block, so stop for now */ - return NULL; - } - if (res == 0) { - /* Client/server has left */ - *status = CloseConnection(cs); - return NULL; - } - p->pos += res; - } - - NetworkRecv_ReadPacketSize(p); - - if (p->size > SEND_MTU) { - *status = CloseConnection(cs); - return NULL; - } - } - - /* Read rest of packet */ - while (p->pos < p->size) { - res = recv(cs->socket, p->buffer + p->pos, p->size - p->pos, 0); - if (res == -1) { - int err = GET_LAST_ERROR(); - if (err != EWOULDBLOCK) { - /* Something went wrong... (104 is connection reset by peer) */ - if (err != 104) DEBUG(net, 0, "recv failed with error %d", err); - *status = CloseConnection(cs); - return NULL; - } - /* Connection would block */ - return NULL; - } - if (res == 0) { - /* Client/server has left */ - *status = CloseConnection(cs); - return NULL; - } - - p->pos += res; - } - - /* We have a complete packet, return it! */ - p->pos = 2; - p->next = NULL; // Should not be needed, but who knows... - - /* Prepare for receiving a new packet */ - cs->packet_recv = NULL; - - return p; -} - -#endif /* ENABLE_NETWORK */ diff --git a/network/core/tcp.h b/network/core/tcp.h deleted file mode 100644 index e3c307353..000000000 --- a/network/core/tcp.h +++ /dev/null @@ -1,60 +0,0 @@ -/* $Id$ */ - -#ifndef NETWORK_CORE_TCP_H -#define NETWORK_CORE_TCP_H - -#ifdef ENABLE_NETWORK - -/** - * @file tcp.h Basic functions to receive and send TCP packets. - */ - -/** - * Enum with all types of UDP packets. - * The order of the first 4 packets MUST not be changed, as - * it protects old clients from joining newer servers - * (because SERVER_ERROR is the respond to a wrong revision) - */ -enum { - PACKET_SERVER_FULL, - PACKET_SERVER_BANNED, - PACKET_CLIENT_JOIN, - PACKET_SERVER_ERROR, - PACKET_CLIENT_COMPANY_INFO, - PACKET_SERVER_COMPANY_INFO, - PACKET_SERVER_CLIENT_INFO, - PACKET_SERVER_NEED_PASSWORD, - PACKET_CLIENT_PASSWORD, - PACKET_SERVER_WELCOME, - PACKET_CLIENT_GETMAP, - PACKET_SERVER_WAIT, - PACKET_SERVER_MAP, - PACKET_CLIENT_MAP_OK, - PACKET_SERVER_JOIN, - PACKET_SERVER_FRAME, - PACKET_SERVER_SYNC, - PACKET_CLIENT_ACK, - PACKET_CLIENT_COMMAND, - PACKET_SERVER_COMMAND, - PACKET_CLIENT_CHAT, - PACKET_SERVER_CHAT, - PACKET_CLIENT_SET_PASSWORD, - PACKET_CLIENT_SET_NAME, - PACKET_CLIENT_QUIT, - PACKET_CLIENT_ERROR, - PACKET_SERVER_QUIT, - PACKET_SERVER_ERROR_QUIT, - PACKET_SERVER_SHUTDOWN, - PACKET_SERVER_NEWGAME, - PACKET_SERVER_RCON, - PACKET_CLIENT_RCON, - PACKET_END ///< Must ALWAYS be on the end of this list!! (period) -}; - -void NetworkSend_Packet(Packet *packet, NetworkClientState *cs); -Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status); -bool NetworkSend_Packets(NetworkClientState *cs); - -#endif /* ENABLE_NETWORK */ - -#endif /* NETWORK_CORE_TCP_H */ diff --git a/network/core/udp.c b/network/core/udp.c deleted file mode 100644 index badd9a532..000000000 --- a/network/core/udp.c +++ /dev/null @@ -1,277 +0,0 @@ -/* $Id$ */ - -#ifdef ENABLE_NETWORK - -#include "../../stdafx.h" -#include "../../date.h" -#include "../../debug.h" -#include "../../macros.h" -#include "../../newgrf_config.h" - -#include "os_abstraction.h" -#include "config.h" -#include "game.h" -#include "packet.h" -#include "udp.h" - -/** - * @file udp.c Basic functions to receive and send UDP packets. - */ - -/** - * Send a packet over UDP - * @param udp the socket to send over - * @param p the packet to send - * @param recv the receiver (target) of the packet - */ -void NetworkSendUDP_Packet(SOCKET udp, Packet *p, struct sockaddr_in *recv) -{ - int res; - - NetworkSend_FillPacketSize(p); - - /* Send the buffer */ - res = sendto(udp, p->buffer, p->size, 0, (struct sockaddr *)recv, sizeof(*recv)); - - /* Check for any errors, but ignore it otherwise */ - if (res == -1) DEBUG(net, 1, "[udp] sendto failed with: %i", GET_LAST_ERROR()); -} - -/** - * Start listening on the given host and port. - * @param udp the place where the (references to the) UDP are stored - * @param host the host (ip) to listen on - * @param port the port to listen on - * @param broadcast whether to allow broadcast sending/receiving - * @return true if the listening succeeded - */ -bool NetworkUDPListen(SOCKET *udp, uint32 host, uint16 port, bool broadcast) -{ - struct sockaddr_in sin; - - /* Make sure socket is closed */ - closesocket(*udp); - - *udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (*udp == INVALID_SOCKET) { - DEBUG(net, 0, "[udp] failed to start UDP listener"); - return false; - } - - /* set nonblocking mode for socket */ - { - unsigned long blocking = 1; -#ifndef BEOS_NET_SERVER - ioctlsocket(*udp, FIONBIO, &blocking); -#else - setsockopt(*udp, SOL_SOCKET, SO_NONBLOCK, &blocking, NULL); -#endif - } - - sin.sin_family = AF_INET; - /* Listen on all IPs */ - sin.sin_addr.s_addr = host; - sin.sin_port = htons(port); - - if (bind(*udp, (struct sockaddr*)&sin, sizeof(sin)) != 0) { - DEBUG(net, 0, "[udp] bind failed on %s:%i", inet_ntoa(*(struct in_addr *)&host), port); - return false; - } - - if (broadcast) { - /* Enable broadcast */ - unsigned long val = 1; -#ifndef BEOS_NET_SERVER // will work around this, some day; maybe. - setsockopt(*udp, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val)); -#endif - } - - DEBUG(net, 1, "[udp] listening on port %s:%d", inet_ntoa(*(struct in_addr *)&host), port); - - return true; -} - -/** - * Receive a packet at UDP level - * @param udp the socket to receive the packet on - */ -void NetworkUDPReceive(SOCKET udp) -{ - struct sockaddr_in client_addr; - socklen_t client_len; - int nbytes; - Packet p; - int packet_len; - - packet_len = sizeof(p.buffer); - client_len = sizeof(client_addr); - - /* Try to receive anything */ - nbytes = recvfrom(udp, p.buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len); - - /* We got some bytes for the base header of the packet. - * Assume we received the whole packet. */ - if (nbytes > 2) { - NetworkRecv_ReadPacketSize(&p); - - /* Put the position on the right place */ - p.pos = 2; - p.next = NULL; - - /* Handle the packet */ - NetworkHandleUDPPacket(&p, &client_addr); - } -} - - -/** - * Serializes the GRFIdentifier (GRF ID and MD5 checksum) to the packet - * @param p the packet to write the data to - * @param c the configuration to write the GRF ID and MD5 checksum from - */ -void NetworkSend_GRFIdentifier(Packet *p, const GRFConfig *c) -{ - uint j; - NetworkSend_uint32(p, c->grfid); - for (j = 0; j < sizeof(c->md5sum); j++) { - NetworkSend_uint8 (p, c->md5sum[j]); - } -} - -/** - * Deserializes the GRFIdentifier (GRF ID and MD5 checksum) from the packet - * @param cs the client state (for closing connect on out-of-bounds reading etc) - * @param p the packet to read the data from - * @param c the configuration to write the GRF ID and MD5 checksum to - */ -void NetworkRecv_GRFIdentifier(NetworkClientState *cs, Packet *p, GRFConfig *c) -{ - uint j; - c->grfid = NetworkRecv_uint32(cs, p); - for (j = 0; j < sizeof(c->md5sum); j++) { - c->md5sum[j] = NetworkRecv_uint8(cs, p); - } -} - - -/** - * Serializes the NetworkGameInfo struct to the packet - * @param p the packet to write the data to - * @param info the NetworkGameInfo struct to serialize - */ -void NetworkSend_NetworkGameInfo(Packet *p, const NetworkGameInfo *info) -{ - NetworkSend_uint8 (p, NETWORK_GAME_INFO_VERSION); - - /* - * Please observe the order. - * The parts must be read in the same order as they are sent! - */ - - - /* NETWORK_GAME_INFO_VERSION = 4 */ - { - /* Only send the GRF Identification (GRF_ID and MD5 checksum) of - * the GRFs that are needed, i.e. the ones that the server has - * selected in the NewGRF GUI and not the ones that are used due - * to the fact that they are in [newgrf-static] in openttd.cfg */ - const GRFConfig *c; - uint count = 0; - - /* Count number of GRFs to send information about */ - for (c = info->grfconfig; c != NULL; c = c->next) { - if (!HASBIT(c->flags, GCF_STATIC)) count++; - } - NetworkSend_uint8 (p, count); // Send number of GRFs - - /* Send actual GRF Identifications */ - for (c = info->grfconfig; c != NULL; c = c->next) { - if (!HASBIT(c->flags, GCF_STATIC)) NetworkSend_GRFIdentifier(p, c); - } - } - - /* NETWORK_GAME_INFO_VERSION = 3 */ - NetworkSend_uint32(p, info->game_date); - NetworkSend_uint32(p, info->start_date); - - /* NETWORK_GAME_INFO_VERSION = 2 */ - NetworkSend_uint8 (p, info->companies_max); - NetworkSend_uint8 (p, info->companies_on); - NetworkSend_uint8 (p, info->spectators_max); - - /* NETWORK_GAME_INFO_VERSION = 1 */ - NetworkSend_string(p, info->server_name); - NetworkSend_string(p, info->server_revision); - NetworkSend_uint8 (p, info->server_lang); - NetworkSend_uint8 (p, info->use_password); - NetworkSend_uint8 (p, info->clients_max); - NetworkSend_uint8 (p, info->clients_on); - NetworkSend_uint8 (p, info->spectators_on); - NetworkSend_string(p, info->map_name); - NetworkSend_uint16(p, info->map_width); - NetworkSend_uint16(p, info->map_height); - NetworkSend_uint8 (p, info->map_set); - NetworkSend_uint8 (p, info->dedicated); -} - -/** - * Deserializes the NetworkGameInfo struct from the packet - * @param cs the client state (for closing connect on out-of-bounds reading etc) - * @param p the packet to read the data from - * @param info the NetworkGameInfo to deserialize into - */ -void NetworkRecv_NetworkGameInfo(NetworkClientState *cs, Packet *p, NetworkGameInfo *info) -{ - info->game_info_version = NetworkRecv_uint8(cs, p); - - /* - * Please observe the order. - * The parts must be read in the same order as they are sent! - */ - - switch (info->game_info_version) { - case 4: { - GRFConfig *c, **dst = &info->grfconfig; - uint i; - uint num_grfs = NetworkRecv_uint8(cs, p); - - for (i = 0; i < num_grfs; i++) { - c = calloc(1, sizeof(*c)); - NetworkRecv_GRFIdentifier(cs, p, c); - HandleIncomingNetworkGameInfoGRFConfig(c); - - /* Append GRFConfig to the list */ - *dst = c; - dst = &c->next; - } - } /* Fallthrough */ - case 3: - info->game_date = NetworkRecv_uint32(cs, p); - info->start_date = NetworkRecv_uint32(cs, p); - /* Fallthrough */ - case 2: - info->companies_max = NetworkRecv_uint8 (cs, p); - info->companies_on = NetworkRecv_uint8 (cs, p); - info->spectators_max = NetworkRecv_uint8 (cs, p); - /* Fallthrough */ - case 1: - NetworkRecv_string(cs, p, info->server_name, sizeof(info->server_name)); - NetworkRecv_string(cs, p, info->server_revision, sizeof(info->server_revision)); - info->server_lang = NetworkRecv_uint8 (cs, p); - info->use_password = NetworkRecv_uint8 (cs, p); - info->clients_max = NetworkRecv_uint8 (cs, p); - info->clients_on = NetworkRecv_uint8 (cs, p); - info->spectators_on = NetworkRecv_uint8 (cs, p); - if (info->game_info_version < 3) { // 16 bits dates got scrapped and are read earlier - info->game_date = NetworkRecv_uint16(cs, p) + DAYS_TILL_ORIGINAL_BASE_YEAR; - info->start_date = NetworkRecv_uint16(cs, p) + DAYS_TILL_ORIGINAL_BASE_YEAR; - } - NetworkRecv_string(cs, p, info->map_name, sizeof(info->map_name)); - info->map_width = NetworkRecv_uint16(cs, p); - info->map_height = NetworkRecv_uint16(cs, p); - info->map_set = NetworkRecv_uint8 (cs, p); - info->dedicated = NetworkRecv_uint8 (cs, p); - } -} - -#endif /* ENABLE_NETWORK */ diff --git a/network/core/udp.h b/network/core/udp.h deleted file mode 100644 index 3221e664f..000000000 --- a/network/core/udp.h +++ /dev/null @@ -1,62 +0,0 @@ -/* $Id$ */ - -#ifndef NETWORK_CORE_UDP_H -#define NETWORK_CORE_UDP_H - -#ifdef ENABLE_NETWORK - -/** - * @file udp.h Basic functions to receive and send UDP packets. - */ - -///** Sending/receiving of UDP packets **//// - -void NetworkSendUDP_Packet(SOCKET udp, Packet *p, struct sockaddr_in *recv); -bool NetworkUDPListen(SOCKET *udp, uint32 host, uint16 port, bool broadcast); -void NetworkUDPReceive(SOCKET udp); - -/** - * Function that is called for every received UDP packet. - * @param packet the received packet - * @param client_addr the address of the sender of the packet - */ -void NetworkHandleUDPPacket(Packet *p, struct sockaddr_in *client_addr); - - -///** Sending/receiving of (large) chuncks of UDP packets **//// - - -/** Enum with all types of UDP packets. The order MUST not be changed **/ -enum { - PACKET_UDP_CLIENT_FIND_SERVER, ///< Queries a game server for game information - PACKET_UDP_SERVER_RESPONSE, ///< Reply of the game server with game information - PACKET_UDP_CLIENT_DETAIL_INFO, ///< Queries a game server about details of the game, such as companies - PACKET_UDP_SERVER_DETAIL_INFO, ///< Reply of the game server about details of the game, such as companies - PACKET_UDP_SERVER_REGISTER, ///< Packet to register itself to the master server - PACKET_UDP_MASTER_ACK_REGISTER, ///< Packet indicating registration has succedeed - PACKET_UDP_CLIENT_GET_LIST, ///< Request for serverlist from master server - PACKET_UDP_MASTER_RESPONSE_LIST, ///< Response from master server with server ip's + port's - PACKET_UDP_SERVER_UNREGISTER, ///< Request to be removed from the server-list - PACKET_UDP_CLIENT_GET_NEWGRFS, ///< Requests the name for a list of GRFs (GRF_ID and MD5) - PACKET_UDP_SERVER_NEWGRFS, ///< Sends the list of NewGRF's requested. - PACKET_UDP_END ///< Must ALWAYS be on the end of this list!! (period) -}; - -void NetworkSend_GRFIdentifier(Packet *p, const GRFConfig *c); -void NetworkSend_NetworkGameInfo(Packet *p, const NetworkGameInfo *info); - -void NetworkRecv_GRFIdentifier(NetworkClientState *cs, Packet *p, GRFConfig *c); -void NetworkRecv_NetworkGameInfo(NetworkClientState *cs, Packet *p, NetworkGameInfo *info); - -/** - * Function that is called for every GRFConfig that is read when receiving - * a NetworkGameInfo. Only grfid and md5sum are set, the rest is zero. This - * function must set all appropriate fields. This GRF is later appended to - * the grfconfig list of the NetworkGameInfo. - * @param config the GRF to handle - */ -void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config); - -#endif /* ENABLE_NETWORK */ - -#endif /* NETWORK_CORE_UDP_H */ |