Changeset - r1343:ea7fb505ae74
[Not reviewed]
master
0 2 0
tron - 20 years ago 2005-02-08 15:42:28
tron@openttd.org
(svn r1847) Adjustment for MorphOS to unbreak the build there and removal of some now obsolete preprocessor magic
2 files changed with 3 insertions and 5 deletions:
0 comments (0 inline, 0 general)
network_core.h
Show inline comments
 
@@ -27,140 +27,142 @@
 
#define GET_LAST_ERROR() WSAGetLastError()
 
#define EWOULDBLOCK WSAEWOULDBLOCK
 
// Windows has some different names for some types..
 
typedef unsigned long in_addr_t;
 
typedef INTERFACE_INFO IFREQ;
 
#endif // WIN32
 

	
 
// UNIX stuff
 
#if defined(UNIX)
 
#	define SOCKET int
 
#	define INVALID_SOCKET -1
 
typedef struct ifreq IFREQ;
 
#	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>
 
#		if !defined(SUNOS) && !defined(__MORPHOS__) && !defined(__BEOS__)
 
#			include <ifaddrs.h>
 
// If for any reason ifaddrs.h does not exist on a system, remove define below
 
//   and an other system will be used to fetch ips from the system
 
#			define HAVE_GETIFADDRS
 
#		else
 
#			define INADDR_NONE 0xffffffff
 
#		endif // SUNOS
 
#		if defined(__BEOS__) && !defined(BEOS_NET_SERVER)
 
			// needed on Zeta
 
#			include <sys/sockio.h>
 
#		endif
 
#	endif // BEOS_NET_SERVER
 

	
 
/* GLibc 2.1 does not support GetIfAddr() */
 
#	if defined(__GLIBC__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 1)
 
#		undef HAVE_GETIFADDRS
 
		typedef uint32_t in_addr_t;
 
#	endif /* __GLIBC__ && (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 1) */
 

	
 
#	include <errno.h>
 
#	include <sys/time.h>
 
#	include <netdb.h>
 
#endif // UNIX
 

	
 
// OS/2 stuff
 
#if defined(__OS2__)
 
#	define SOCKET int
 
#	define INVALID_SOCKET -1
 
typedef struct ifreq IFREQ;
 
#	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 unsigned long in_addr_t;
 
#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)
 
{
 
	int nonblocking = 1;
 
	#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 // NETWORK_CORE_H
network_udp.c
Show inline comments
 
@@ -309,197 +309,193 @@ void NetworkHandleUDPPacket(Packet *p, s
 
	}	else {
 
		DEBUG(net, 0)("[NET][UDP] Received invalid packet type %d", type);
 
	}
 
}
 

	
 

	
 
// Send a packet over UDP
 
void NetworkSendUDP_Packet(SOCKET udp, Packet *p, struct sockaddr_in *recv)
 
{
 
	int res;
 

	
 
	// Put the length in the buffer
 
	p->buffer[0] = p->size & 0xFF;
 
	p->buffer[1] = p->size >> 8;
 

	
 
	// Send the buffer
 
	res = sendto(udp, p->buffer, p->size, 0, (struct sockaddr *)recv, sizeof(*recv));
 

	
 
	// Check for any errors, but ignore it for the rest
 
	if (res == -1) {
 
		DEBUG(net, 1)("[NET][UDP] Send error: %i", GET_LAST_ERROR());
 
	}
 
}
 

	
 
// Start UDP listener
 
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, 1)("[NET][UDP] Failed to start UDP support");
 
		return false;
 
	}
 

	
 
	// set nonblocking mode for socket
 
	{
 
		unsigned long blocking = 1;
 
		ioctlsocket(*udp, FIONBIO, &blocking);
 
	}
 

	
 
	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, 1) ("[NET][UDP] error: bind failed on %s:%i", inet_ntoa(*(struct in_addr *)&host), port);
 
		return false;
 
	}
 

	
 
	if (broadcast) {
 
		/* Enable broadcast */
 
		unsigned long val = 1;
 
		setsockopt(*udp, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val));
 
	}
 

	
 
	DEBUG(net, 1)("[NET][UDP] Listening on port %s:%d", inet_ntoa(*(struct in_addr *)&host), port);
 

	
 
	return true;
 
}
 

	
 
// Close UDP connection
 
void NetworkUDPClose(void)
 
{
 
	DEBUG(net, 1) ("[NET][UDP] Closed listeners");
 

	
 
	if (_network_udp_server) {
 
		if (_udp_server_socket != INVALID_SOCKET) {
 
			closesocket(_udp_server_socket);
 
			_udp_server_socket = INVALID_SOCKET;
 
		}
 

	
 
		if (_udp_master_socket != INVALID_SOCKET) {
 
			closesocket(_udp_master_socket);
 
			_udp_master_socket = INVALID_SOCKET;
 
		}
 

	
 
		_network_udp_server = false;
 
		_network_udp_broadcast = 0;
 
	} else {
 
		if (_udp_client_socket != INVALID_SOCKET) {
 
			closesocket(_udp_client_socket);
 
			_udp_client_socket = INVALID_SOCKET;
 
		}
 
		_network_udp_broadcast = 0;
 
	}
 
}
 

	
 
// Receive something on UDP level
 
void NetworkUDPReceive(SOCKET udp)
 
{
 
	struct sockaddr_in client_addr;
 
#ifndef __MORPHOS__
 
	int client_len;
 
#else
 
	LONG client_len; // for some reason we need a 'LONG' under MorphOS
 
#endif
 
	socklen_t client_len;
 
	int nbytes;
 
	static Packet *p = NULL;
 
	int packet_len;
 

	
 
	// If p is NULL, malloc him.. this prevents unneeded mallocs
 
	if (p == NULL)
 
		p = malloc(sizeof(Packet));
 

	
 
	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.. just asume we receive the whole packet
 
	if (nbytes > 0) {
 
		// Get the size of the buffer
 
		p->size = (uint16)p->buffer[0];
 
		p->size += (uint16)p->buffer[1] << 8;
 
		// Put the position on the right place
 
		p->pos = 2;
 
		p->next = NULL;
 

	
 
		// Handle the packet
 
		NetworkHandleUDPPacket(p, &client_addr);
 

	
 
		// Free the packet
 
		free(p);
 
		p = NULL;
 
	}
 
}
 

	
 
// Broadcast to all ips
 
void NetworkUDPBroadCast(SOCKET udp)
 
{
 
	int i;
 
	struct sockaddr_in out_addr;
 
	byte *bcptr;
 
	uint32 bcaddr;
 
	Packet *p;
 

	
 
	// Init the packet
 
	p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
 

	
 
	// Go through all the ips on this pc
 
	i = 0;
 
	while (_network_ip_list[i] != 0) {
 
		bcaddr = _network_ip_list[i];
 
		bcptr = (byte *)&bcaddr;
 
		// Make the address a broadcast address
 
		bcptr[3] = 255;
 

	
 
		DEBUG(net, 6)("[NET][UDP] Broadcasting to %s", inet_ntoa(*(struct in_addr *)&bcaddr));
 

	
 
		out_addr.sin_family = AF_INET;
 
		out_addr.sin_port = htons(_network_server_port);
 
		out_addr.sin_addr.s_addr = bcaddr;
 

	
 
		NetworkSendUDP_Packet(udp, p, &out_addr);
 

	
 
		i++;
 
	}
 
}
 

	
 

	
 
// Request the the server-list from the master server
 
void NetworkUDPQueryMasterServer(void)
 
{
 
	struct sockaddr_in out_addr;
 
	Packet *p;
 

	
 
	if (_udp_client_socket == INVALID_SOCKET)
 
		if (!NetworkUDPListen(&_udp_client_socket, 0, 0, true))
 
			return;
 

	
 
	p = NetworkSend_Init(PACKET_UDP_CLIENT_GET_LIST);
 

	
 
	out_addr.sin_family = AF_INET;
 
	out_addr.sin_port = htons(NETWORK_MASTER_SERVER_PORT);
 
	out_addr.sin_addr.s_addr = NetworkResolveHost(NETWORK_MASTER_SERVER_HOST);
 

	
 
	// packet only contains protocol version
 
	NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
 

	
 
	NetworkSendUDP_Packet(_udp_client_socket, p, &out_addr);
 

	
 
	DEBUG(net, 2)("[NET][UDP] Queried Master Server at %s:%d", inet_ntoa(out_addr.sin_addr),ntohs(out_addr.sin_port));
 

	
 
	free(p);
 
}
 

	
 
// Find all servers
 
void NetworkUDPSearchGame(void)
 
{
 
	// We are still searching..
 
	if (_network_udp_broadcast > 0)
0 comments (0 inline, 0 general)