ObjFW  Check-in [6e9ee122eb]

Overview
Comment:Remove resolver.m

Instead, OFDNSResolver is used for everything now.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 6e9ee122eb2336a5e6f730393a100df61649f011a00dd3fd687cca8f30cfe82a
User & Date: js on 2018-10-07 02:06:46
Other Links: manifest | tags
Context
2018-10-07
02:39
OFDNSResolver: Look at static hosts to get address check-in: 4d335e89d6 user: js tags: trunk
02:06
Remove resolver.m check-in: 6e9ee122eb user: js tags: trunk
2018-10-06
20:21
OFDNSResolver: Add sync resolve socket addresses check-in: 22700e6082 user: js tags: trunk
Changes

Modified configure.ac from [0289c3600c] to [ca5e9322d2].

1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
					[Whether we have select() or similar])
				AC_SUBST(OFKERNELEVENTOBSERVER_SELECT_M,
					"OFKernelEventObserver_select.m")
			])
			;;
	esac

	AC_MSG_CHECKING(for getaddrinfo)
	AC_TRY_COMPILE([
		#include <stddef.h>
		#ifdef OF_HAVE_SYS_TYPES_H
		# include <sys/types.h>
		#endif
		#ifdef HAVE_SYS_SOCKET_H
		# include <sys/socket.h>
		#endif
		#ifdef HAVE_NETDB_H
		# include <netdb.h>
		#endif
		#ifdef _WIN32
		typedef unsigned char BOOL;
		# include <ws2tcpip.h>
		#endif
	], [
		struct addrinfo ai;
		getaddrinfo(NULL, NULL, NULL, NULL);
	], [
		AC_MSG_RESULT(yes)
		AC_DEFINE(HAVE_GETADDRINFO, 1, [Whether we have getaddrinfo()])

		AS_IF([test x"$enable_threads" != x"no"], [
			AC_MSG_CHECKING(whether getaddrinfo is thread-safe)

			case "$host_os" in
				darwin[[12345]].*)
					have_threadsafe_getaddrinfo="no"
					;;
				darwin*)
					have_threadsafe_getaddrinfo="yes"
					;;
				freebsd[[1234]].* | freebsd5.[[1234]]*)
					have_threadsafe_getaddrinfo="no"
					;;
				freebsd*)
					have_threadsafe_getaddrinfo="yes"
					;;
				netbsd[[123]].*)
					have_threadsafe_getaddrinfo="no"
					;;
				netbsd*)
					have_threadsafe_getaddrinfo="yes"
					;;
				solaris*)
					have_threadsafe_getaddrinfo="yes"
					;;
				*)
					have_threadsafe_getaddrinfo="unknown"
					;;
			esac

			AS_IF([test x"$have_threadsafe_getaddrinfo" = \
					x"unknown"], [
				AC_EGREP_CPP(egrep_cpp_yes, [
					#ifdef OF_HAVE_SYS_TYPES_H
					# include <sys/types.h>
					#endif
					#ifdef HAVE_SYS_SOCKET_H
					# include <sys/socket.h>
					#endif
					#ifdef HAVE_NETDB_H
					# include <netdb.h>
					#endif
					#ifdef _WIN32
					# define _WIN32_WINNT 0x0501
					# include <windows.h>
					# include <ws2tcpip.h>
					#endif

					#ifdef h_errno
					egrep_cpp_yes
					#end
				], [
					have_threadsafe_getaddrinfo="yes"
				], [
					have_threadsafe_getaddrinfo="no"
				])
			])

			AS_IF([test x"$have_threadsafe_getaddrinfo" = x"yes"], [
				AC_DEFINE(HAVE_THREADSAFE_GETADDRINFO, 1,
					[Whether getaddrinfo is thread-safe])
			])

			AC_MSG_RESULT($have_threadsafe_getaddrinfo)
		])
	], [
		AC_MSG_RESULT(no)
	])

	AS_IF([test x"$enable_threads" != x"no"], [
		AC_SUBST(OFHTTPCLIENTTESTS_M, "OFHTTPClientTests.m")
	])

	AC_SUBST(OFDNS, "ofdns")
	AS_IF([test x"$enable_files" != x"no"], [
		AC_SUBST(OFHTTP, "ofhttp")







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1304
1305
1306
1307
1308
1309
1310




























































































1311
1312
1313
1314
1315
1316
1317
					[Whether we have select() or similar])
				AC_SUBST(OFKERNELEVENTOBSERVER_SELECT_M,
					"OFKernelEventObserver_select.m")
			])
			;;
	esac





























































































	AS_IF([test x"$enable_threads" != x"no"], [
		AC_SUBST(OFHTTPCLIENTTESTS_M, "OFHTTPClientTests.m")
	])

	AC_SUBST(OFDNS, "ofdns")
	AS_IF([test x"$enable_files" != x"no"], [
		AC_SUBST(OFHTTP, "ofhttp")

Modified src/Makefile from [d620634847] to [25efe5c01f].

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
	       OFHTTPCookieManager.m		\
	       OFHTTPRequest.m			\
	       OFHTTPResponse.m			\
	       OFHTTPServer.m			\
	       OFStreamSocket.m			\
	       OFTCPSocket.m			\
	       OFUDPSocket.m			\
	       resolver.m			\
	       socket.m
SRCS_THREADS = OFCondition.m		\
	       OFMutex.m		\
	       OFRecursiveMutex.m	\
	       OFThreadPool.m		\
	       threading.m
SRCS_WINDOWS = OFStdIOStream_Win32Console.m	\







<







130
131
132
133
134
135
136

137
138
139
140
141
142
143
	       OFHTTPCookieManager.m		\
	       OFHTTPRequest.m			\
	       OFHTTPResponse.m			\
	       OFHTTPServer.m			\
	       OFStreamSocket.m			\
	       OFTCPSocket.m			\
	       OFUDPSocket.m			\

	       socket.m
SRCS_THREADS = OFCondition.m		\
	       OFMutex.m		\
	       OFRecursiveMutex.m	\
	       OFThreadPool.m		\
	       threading.m
SRCS_WINDOWS = OFStdIOStream_Win32Console.m	\

Modified src/OFDNSResolver.m from [8f4fd230d2] to [f094c42133].

30
31
32
33
34
35
36

37
38
39
40
41
42
43
#import "OFFile.h"
#import "OFLocale.h"
#import "OFNumber.h"
#import "OFPair.h"
#import "OFString.h"
#import "OFTimer.h"
#import "OFUDPSocket.h"

#ifdef OF_WINDOWS
# import "OFWindowsRegistryKey.h"
#endif

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"







>







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#import "OFFile.h"
#import "OFLocale.h"
#import "OFNumber.h"
#import "OFPair.h"
#import "OFString.h"
#import "OFTimer.h"
#import "OFUDPSocket.h"
#import "OFUDPSocket+Private.h"
#ifdef OF_WINDOWS
# import "OFWindowsRegistryKey.h"
#endif

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
1780
1781
1782
1783
1784
1785
1786



1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797



1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
	    objectAtIndex: query->_nameServersIndex];
	query->_usedNameServer = of_socket_address_parse_ip(nameServer, 53);

	switch (query->_usedNameServer.family) {
#ifdef OF_HAVE_IPV6
	case OF_SOCKET_ADDRESS_FAMILY_IPV6:
		if (_IPv6Socket == nil) {



			_IPv6Socket = [[OFUDPSocket alloc] init];
			[_IPv6Socket bindToHost: @"::"
					   port: 0];
			[_IPv6Socket setBlocking: false];
		}

		sock = _IPv6Socket;
		break;
#endif
	case OF_SOCKET_ADDRESS_FAMILY_IPV4:
		if (_IPv4Socket == nil) {



			_IPv4Socket = [[OFUDPSocket alloc] init];
			[_IPv4Socket bindToHost: @"0.0.0.0"
					   port: 0];
			[_IPv4Socket setBlocking: false];
		}

		sock = _IPv4Socket;
		break;
	default:
		@throw [OFInvalidArgumentException exception];







>
>
>

|
<








>
>
>

|
<







1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792

1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805

1806
1807
1808
1809
1810
1811
1812
	    objectAtIndex: query->_nameServersIndex];
	query->_usedNameServer = of_socket_address_parse_ip(nameServer, 53);

	switch (query->_usedNameServer.family) {
#ifdef OF_HAVE_IPV6
	case OF_SOCKET_ADDRESS_FAMILY_IPV6:
		if (_IPv6Socket == nil) {
			of_socket_address_t address =
			    of_socket_address_parse_ip(@"::", 0);

			_IPv6Socket = [[OFUDPSocket alloc] init];
			[_IPv6Socket of_bindToAddress: &address];

			[_IPv6Socket setBlocking: false];
		}

		sock = _IPv6Socket;
		break;
#endif
	case OF_SOCKET_ADDRESS_FAMILY_IPV4:
		if (_IPv4Socket == nil) {
			of_socket_address_t address =
			    of_socket_address_parse_ip(@"0.0.0.0", 0);

			_IPv4Socket = [[OFUDPSocket alloc] init];
			[_IPv4Socket of_bindToAddress: &address];

			[_IPv4Socket setBlocking: false];
		}

		sock = _IPv4Socket;
		break;
	default:
		@throw [OFInvalidArgumentException exception];
2069
2070
2071
2072
2073
2074
2075






















2076
2077
2078
2079
2080
2081
2082
			       runLoopMode: (of_run_loop_mode_t)runLoopMode
				    target: (id)target
				  selector: (SEL)selector
				   context: (id)userContext
{
	void *pool = objc_autoreleasePoolPush();
	OFDNSResolver_AsyncResolveSocketAddressesContext *context;























	context = [[[OFDNSResolver_AsyncResolveSocketAddressesContext alloc]
	    initWithHost: host
		  target: target
		selector: selector
		 context: userContext] autorelease];








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
			       runLoopMode: (of_run_loop_mode_t)runLoopMode
				    target: (id)target
				  selector: (SEL)selector
				   context: (id)userContext
{
	void *pool = objc_autoreleasePoolPush();
	OFDNSResolver_AsyncResolveSocketAddressesContext *context;

	@try {
		of_socket_address_t address =
		    of_socket_address_parse_ip(host, 0);
		OFData *addresses;
		void (*method)(id, SEL, OFDNSResolver *, OFString *, OFData *,
		    id, id);

		if (addressFamily != OF_SOCKET_ADDRESS_FAMILY_ANY &&
		    address.family != addressFamily)
			@throw [OFInvalidArgumentException exception];

		addresses = [OFData dataWithItems: &address
				    itemSize: sizeof(address)
				       count: 1];

		method = (void (*)(id, SEL, OFDNSResolver *, OFString *,
		    OFData *, id, id))[target methodForSelector: selector];
		method(target, selector, self, host, addresses, userContext,
		    nil);
	} @catch (OFInvalidFormatException *e) {
	}

	context = [[[OFDNSResolver_AsyncResolveSocketAddressesContext alloc]
	    initWithHost: host
		  target: target
		selector: selector
		 context: userContext] autorelease];

Modified src/OFRunLoop.m from [54ecb2a574] to [b99d9d1539].

1137
1138
1139
1140
1141
1142
1143

1144
1145
1146
1147
1148
1149
1150
		   beforeDate: deadline];
}

- (void)runMode: (of_run_loop_mode_t)mode
     beforeDate: (OFDate *)deadline
{
	void *pool = objc_autoreleasePoolPush();

	OFRunLoop_State *state = [self of_stateForMode: mode
						create: false];

	if (state == nil)
		return;

	_currentMode = mode;







>







1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
		   beforeDate: deadline];
}

- (void)runMode: (of_run_loop_mode_t)mode
     beforeDate: (OFDate *)deadline
{
	void *pool = objc_autoreleasePoolPush();
	of_run_loop_mode_t previousMode = _currentMode;
	OFRunLoop_State *state = [self of_stateForMode: mode
						create: false];

	if (state == nil)
		return;

	_currentMode = mode;
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
#else
			[OFThread sleepForTimeInterval: 86400];
#endif
		}

		objc_autoreleasePoolPop(pool);
	} @finally {
		_currentMode = nil;
	}
}

- (void)stop
{
	OFRunLoop_State *state = [self of_stateForMode: of_run_loop_mode_default
						create: false];







|







1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
#else
			[OFThread sleepForTimeInterval: 86400];
#endif
		}

		objc_autoreleasePoolPop(pool);
	} @finally {
		_currentMode = previousMode;
	}
}

- (void)stop
{
	OFRunLoop_State *state = [self of_stateForMode: of_run_loop_mode_default
						create: false];

Modified src/OFTCPSocket.m from [2642e89679] to [0378e7d3f9].

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#import "OFNotOpenException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"
#import "OFSetOptionFailedException.h"

#import "socket.h"
#import "socket_helpers.h"
#import "resolver.h"

Class of_tls_socket_class = Nil;

static of_run_loop_mode_t connectRunLoopMode = @"of_tcp_socket_connect_mode";
static OFString *defaultSOCKS5Host = nil;
static uint16_t defaultSOCKS5Port = 1080;








<







53
54
55
56
57
58
59

60
61
62
63
64
65
66
#import "OFNotOpenException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"
#import "OFSetOptionFailedException.h"

#import "socket.h"
#import "socket_helpers.h"


Class of_tls_socket_class = Nil;

static of_run_loop_mode_t connectRunLoopMode = @"of_tcp_socket_connect_mode";
static OFString *defaultSOCKS5Host = nil;
static uint16_t defaultSOCKS5Port = 1080;

862
863
864
865
866
867
868
869
870

871
872


873
874
875
876
877
878
879
880
881

882
883
884
885
886

887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911




























912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980


981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000









1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
	objc_autoreleasePoolPop(pool);
}
#endif

- (uint16_t)bindToHost: (OFString *)host
		  port: (uint16_t)port
{
	of_resolver_result_t **results;
	const int one = 1;

#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
	of_socket_address_t address;


#endif

	if (_socket != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException exceptionWithSocket: self];

	if (_SOCKS5Host != nil)
		@throw [OFNotImplementedException exceptionWithSelector: _cmd
								 object: self];


	results = of_resolve_host(host, port, SOCK_STREAM);
	@try {
#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
		int flags;
#endif


		if ((_socket = socket(results[0]->family,
		    results[0]->type | SOCK_CLOEXEC,
		    results[0]->protocol)) == INVALID_SOCKET)
			@throw [OFBindFailedException
			    exceptionWithHost: host
					 port: port
				       socket: self
					errNo: of_socket_errno()];

		_blocking = true;

#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
		if ((flags = fcntl(_socket, F_GETFD, 0)) != -1)
			fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
#endif

		setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR,
		    (const char *)&one, (socklen_t)sizeof(one));

#if defined(OF_WII) || defined(OF_NINTENDO_3DS)
		if (port != 0) {
#endif
			if (bind(_socket, results[0]->address,
			    results[0]->addressLength) != 0) {




























				int errNo = of_socket_errno();

				closesocket(_socket);
				_socket = INVALID_SOCKET;

				@throw [OFBindFailedException
				    exceptionWithHost: host
						 port: port
					       socket: self
						errNo: errNo];
			}
#if defined(OF_WII) || defined(OF_NINTENDO_3DS)
		} else {
			for (;;) {
				uint16_t rnd = 0;
				int ret;

				while (rnd < 1024)
					rnd = (uint16_t)rand();

				switch (results[0]->family) {
				case AF_INET:
					((struct sockaddr_in *)
					    results[0]->address)->sin_port =
					    OF_BSWAP16_IF_LE(rnd);
					break;
# ifdef OF_HAVE_IPV6
				case AF_INET6:
					((struct sockaddr_in6 *)
					    results[0]->address)->sin6_port =
					    OF_BSWAP16_IF_LE(rnd);
					break;
# endif
				default:
					@throw [OFInvalidArgumentException
					    exception];
				}

				ret = bind(_socket, results[0]->address,
				    results[0]->addressLength);

				if (ret == 0) {
					port = rnd;
					break;
				}

				if (of_socket_errno() != EADDRINUSE) {
					int errNo = of_socket_errno();

					closesocket(_socket);
					_socket = INVALID_SOCKET;

					@throw [OFBindFailedException
					    exceptionWithHost: host
							 port: port
						       socket: self
							errNo: errNo];
				}
			}
		}
#endif
	} @finally {
		of_resolver_free(results);
	}

	if (port > 0)
		return port;

#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)


	address.length = (socklen_t)sizeof(address.sockaddr);
	if (of_getsockname(_socket, &address.sockaddr.sockaddr,
	    &address.length) != 0) {
		int errNo = of_socket_errno();

		closesocket(_socket);
		_socket = INVALID_SOCKET;

		@throw [OFBindFailedException exceptionWithHost: host
							   port: port
							 socket: self
							  errNo: errNo];
	}

	if (address.sockaddr.sockaddr.sa_family == AF_INET)
		return OF_BSWAP16_IF_LE(address.sockaddr.in.sin_port);
# ifdef OF_HAVE_IPV6
	if (address.sockaddr.sockaddr.sa_family == AF_INET6)
		return OF_BSWAP16_IF_LE(address.sockaddr.in6.sin6_port);
# endif









#endif

	closesocket(_socket);
	_socket = INVALID_SOCKET;
	@throw [OFBindFailedException exceptionWithHost: host
						   port: port
						 socket: self
						  errNo: EAFNOSUPPORT];
}

- (void)listen
{
	[self listenWithBacklog: SOMAXCONN];
}








<

>
|

>
>









>
|
<
|
|
|
>

|
<
|
|
|
|
|
|

|


|
|


|
|


|

|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
|
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




>
>

















|


>
>
>
>
>
>
>
>
>







|







861
862
863
864
865
866
867

868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884

885
886
887
888
889
890

891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951





952


953












954



955
956


957
























958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
	objc_autoreleasePoolPop(pool);
}
#endif

- (uint16_t)bindToHost: (OFString *)host
		  port: (uint16_t)port
{

	const int one = 1;
	void *pool = objc_autoreleasePoolPush();
	OFData *socketAddresses;
	of_socket_address_t address;
#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
	int flags;
#endif

	if (_socket != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException exceptionWithSocket: self];

	if (_SOCKS5Host != nil)
		@throw [OFNotImplementedException exceptionWithSelector: _cmd
								 object: self];

	socketAddresses = [[OFThread DNSResolver]
	    resolveSocketAddressesForHost: host

			    addressFamily: OF_SOCKET_ADDRESS_FAMILY_ANY];

	address = *(of_socket_address_t *)[socketAddresses itemAtIndex: 0];
	of_socket_address_set_port(&address, port);

	if ((_socket = socket(address.sockaddr.sockaddr.sa_family,

	    SOCK_STREAM | SOCK_CLOEXEC, 0)) == INVALID_SOCKET)
		@throw [OFBindFailedException
		    exceptionWithHost: host
				 port: port
			       socket: self
				errNo: of_socket_errno()];

	_blocking = true;

#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
	if ((flags = fcntl(_socket, F_GETFD, 0)) != -1)
		fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
#endif

	setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR,
	    (const char *)&one, (socklen_t)sizeof(one));

#if defined(OF_WII) || defined(OF_NINTENDO_3DS)
	if (port != 0) {
#endif
		if (bind(_socket, &address.sockaddr.sockaddr,
		    address.length) != 0) {
			int errNo = of_socket_errno();

			closesocket(_socket);
			_socket = INVALID_SOCKET;

			@throw [OFBindFailedException exceptionWithHost: host
								   port: port
								 socket: self
								  errNo: errNo];
		}
#if defined(OF_WII) || defined(OF_NINTENDO_3DS)
	} else {
		for (;;) {
			uint16_t rnd = 0;
			int ret;

			while (rnd < 1024)
				rnd = (uint16_t)rand();

			of_socket_address_set_port(&address, rnd);

			if ((ret = bind(_socket, &address.sockaddr.sockaddr,
			    address.length)) == 0) {
				port = rnd;
				break;
			}

			if (of_socket_errno() != EADDRINUSE) {
				int errNo = of_socket_errno();

				closesocket(_socket);
				_socket = INVALID_SOCKET;

				@throw [OFBindFailedException
				    exceptionWithHost: host
						 port: port
					       socket: self
						errNo: errNo];
			}





		}


	}












#endif




	objc_autoreleasePoolPop(pool);



























	if (port > 0)
		return port;

#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
	memset(&address, 0, sizeof(address));

	address.length = (socklen_t)sizeof(address.sockaddr);
	if (of_getsockname(_socket, &address.sockaddr.sockaddr,
	    &address.length) != 0) {
		int errNo = of_socket_errno();

		closesocket(_socket);
		_socket = INVALID_SOCKET;

		@throw [OFBindFailedException exceptionWithHost: host
							   port: port
							 socket: self
							  errNo: errNo];
	}

	if (address.sockaddr.sockaddr.sa_family == AF_INET)
		return OF_BSWAP16_IF_LE(address.sockaddr.in.sin_port);
# ifdef OF_HAVE_IPV6
	else if (address.sockaddr.sockaddr.sa_family == AF_INET6)
		return OF_BSWAP16_IF_LE(address.sockaddr.in6.sin6_port);
# endif
	else {
		closesocket(_socket);
		_socket = INVALID_SOCKET;

		@throw [OFBindFailedException exceptionWithHost: host
							   port: port
							 socket: self
							  errNo: EAFNOSUPPORT];
	}
#endif

	closesocket(_socket);
	_socket = INVALID_SOCKET;
	@throw [OFBindFailedException exceptionWithHost: host
						   port: port
						 socket: self
						  errNo: EADDRNOTAVAIL];
}

- (void)listen
{
	[self listenWithBacklog: SOMAXCONN];
}

Added src/OFUDPSocket+Private.h version [9f1517e8f1].





















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
 *               2018
 *   Jonathan Schleifer <js@heap.zone>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFUDPSocket.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFUDPSocket ()
- (uint16_t)of_bindToAddress: (of_socket_address_t *)address;
@end

OF_ASSUME_NONNULL_END

Modified src/OFUDPSocket.h from [29dec683be] to [201326e03a].

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
OF_ASSUME_NONNULL_BEGIN

/*! @file */

@class OFUDPSocket;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief A block which is called when the host / port pair for the UDP socket
 *	  has been resolved.
 *
 * @param host The host that has been resolved
 * @param port The port of the host / port pair
 * @param address The address of the resolved host / port pair
 * @param exception An exception which occurred while resolving or `nil` on
 *		    success
 */
typedef void (^of_udp_socket_async_resolve_block_t)(OFString *host,
    uint16_t port, of_socket_address_t address, id _Nullable exception);

/*!
 * @brief A block which is called when a packet has been received.
 *
 * @param socket The UDP socket which received a packet
 * @param buffer The buffer the packet has been written to
 * @param length The length of the packet
 * @param sender The address of the sender of the packet







<
<
<
<
<
<
<
<
<
<
<
<
<







24
25
26
27
28
29
30













31
32
33
34
35
36
37
OF_ASSUME_NONNULL_BEGIN

/*! @file */

@class OFUDPSocket;

#ifdef OF_HAVE_BLOCKS













/*!
 * @brief A block which is called when a packet has been received.
 *
 * @param socket The UDP socket which received a packet
 * @param buffer The buffer the packet has been written to
 * @param length The length of the packet
 * @param sender The address of the sender of the packet
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#endif

/*!
 * @class OFUDPSocket OFUDPSocket.h ObjFW/OFUDPSocket.h
 *
 * @brief A class which provides methods to create and use UDP sockets.
 *
 * Addresses are of type @ref of_socket_address_t. You can use
 * @ref resolveAddressForHost:port:address: to create an address for a host /
 * port pair and @ref of_socket_address_ip_string to get the IP string / port
 * pair for an address. If you want to compare two addresses, you can use
 * @ref of_socket_address_equal and you can use @ref of_socket_address_hash to
 * get a hash to use in e.g. @ref OFMapTable.
 *
 * @warning Even though the OFCopying protocol is implemented, it does *not*
 *	    return an independent copy of the socket, but instead retains it.
 *	    This is so that the socket can be used as a key for a dictionary,
 *	    so context can be associated with a socket. Using a socket in more
 *	    than one thread at the same time is not thread-safe, even if copy
 *	    was called to create one "instance" for every thread!







|
|
|
|
|
|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#endif

/*!
 * @class OFUDPSocket OFUDPSocket.h ObjFW/OFUDPSocket.h
 *
 * @brief A class which provides methods to create and use UDP sockets.
 *
 * Addresses are of type @ref of_socket_address_t. You can use the current
 * thread's @ref OFDNSResolver to create an address for a host / port pair and
 * @ref of_socket_address_ip_string to get the IP string / port pair for an
 * address. If you want to compare two addresses, you can use @ref
 * of_socket_address_equal and you can use @ref of_socket_address_hash to get a
 * hash to use in e.g. @ref OFMapTable.
 *
 * @warning Even though the OFCopying protocol is implemented, it does *not*
 *	    return an independent copy of the socket, but instead retains it.
 *	    This is so that the socket can be used as a key for a dictionary,
 *	    so context can be associated with a socket. Using a socket in more
 *	    than one thread at the same time is not thread-safe, even if copy
 *	    was called to create one "instance" for every thread!
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*!
 * @brief Returns a new, autoreleased OFUDPSocket.
 *
 * @return A new, autoreleased OFUDPSocket
 */
+ (instancetype)socket;

/*!
 * @brief Resolves the specified host and creates a an address for the host /
 *	  port pair.
 *
 * @param host The host to resolve
 * @param port The port for the resulting address
 * @param address A pointer to the address that should be filled with the
 *		  host / port pair
 */
+ (void)resolveAddressForHost: (OFString *)host
			 port: (uint16_t)port
		      address: (of_socket_address_t *)address;

#ifdef OF_HAVE_THREADS
/*!
 * @brief Asynchronously resolves the specified host and creates an address for
 *	  the host / port pair.
 *
 * @param host The host to resolve
 * @param port The port for the resulting address
 * @param target The target on which to call the selector once the host has been
 *		 resolved
 * @param selector The selector to call on the target. The signature must be
 *		   `void (OFString *host, uint16_t port,
 *		   of_socket_address_t address, id context, id exception)`.
 * @param context A context object to pass along to the target
 */
+ (void)asyncResolveAddressForHost: (OFString *)host
			      port: (uint16_t)port
			    target: (id)target
			  selector: (SEL)selector
			   context: (nullable id)context;

# ifdef OF_HAVE_BLOCKS
/*!
 * @brief Asynchronously resolves the specified host and creates an address for
 *	  the host / port pair.
 *
 * @param host The host to resolve
 * @param port The port for the resulting address
 * @param block The block to execute once the host has been resolved
 */
+ (void)asyncResolveAddressForHost: (OFString *)host
			      port: (uint16_t)port
			     block: (of_udp_socket_async_resolve_block_t)block;
# endif
#endif

/*!
 * @brief Binds the socket to the specified host and port.
 *
 * @param host The host to bind to. Use `@"0.0.0.0"` for IPv4 or `@"::"` for
 *	       IPv6 to bind to all.
 * @param port The port to bind to. If the port is 0, an unused port will be
 *	       chosen, which can be obtained using the return value.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







105
106
107
108
109
110
111
















































112
113
114
115
116
117
118
/*!
 * @brief Returns a new, autoreleased OFUDPSocket.
 *
 * @return A new, autoreleased OFUDPSocket
 */
+ (instancetype)socket;

















































/*!
 * @brief Binds the socket to the specified host and port.
 *
 * @param host The host to bind to. Use `@"0.0.0.0"` for IPv4 or `@"::"` for
 *	       IPv6 to bind to all.
 * @param port The port to bind to. If the port is 0, an unused port will be
 *	       chosen, which can be obtained using the return value.

Modified src/OFUDPSocket.m from [e0fb2ac475] to [073268c5ca].

22
23
24
25
26
27
28
29

30
31
32
33

34

35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#include <string.h>

#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif

#import "OFUDPSocket.h"
#ifdef OF_HAVE_THREADS

# import "OFThread.h"
#endif
#import "OFRunLoop.h"
#import "OFRunLoop+Private.h"



#import "OFBindFailedException.h"
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"

#import "OFNotOpenException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFSetOptionFailedException.h"
#import "OFWriteFailedException.h"

#import "socket.h"
#import "socket_helpers.h"
#import "resolver.h"

#ifdef OF_HAVE_THREADS
@interface OFUDPSocket_ResolveThread: OFThread
{
	OFThread *_sourceThread;
	OFString *_host;
	uint16_t _port;
	id _target;
	SEL _selector;
	id _context;
# ifdef OF_HAVE_BLOCKS
	of_udp_socket_async_resolve_block_t _block;
# endif
	of_socket_address_t _address;
	id _exception;
}

- (instancetype)initWithSourceThread: (OFThread *)sourceThread
				host: (OFString *)host
				port: (uint16_t)port
			      target: (id)target
			    selector: (SEL)selector
			     context: (id)context;
# ifdef OF_HAVE_BLOCKS
- (instancetype)initWithSourceThread: (OFThread *)sourceThread
				host: (OFString *)host
				port: (uint16_t)port
			       block: (of_udp_socket_async_resolve_block_t)
					  block;
# endif
@end

@implementation OFUDPSocket_ResolveThread
- (instancetype)initWithSourceThread: (OFThread *)sourceThread
				host: (OFString *)host
				port: (uint16_t)port
			      target: (id)target
			    selector: (SEL)selector
			     context: (id)context
{
	self = [super init];

	@try {
		_sourceThread = [sourceThread retain];
		_host = [host retain];
		_port = port;
		_target = [target retain];
		_selector = selector;
		_context = [context retain];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

# ifdef OF_HAVE_BLOCKS
- (instancetype)initWithSourceThread: (OFThread *)sourceThread
				host: (OFString *)host
				port: (uint16_t)port
			       block: (of_udp_socket_async_resolve_block_t)block
{
	self = [super init];

	@try {
		_sourceThread = [sourceThread retain];
		_host = [host copy];
		_port = port;
		_block = [block copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
# endif

- (void)dealloc
{
	[_sourceThread release];
	[_host release];
	[_target release];
	[_context release];
# ifdef OF_HAVE_BLOCKS
	[_block release];
# endif
	[_exception release];

	[super dealloc];
}

- (void)didResolve
{
	[self join];

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		_block(_host, _port, _address, _exception);
	else {
# endif
		void (*func)(id, SEL, OFString *, uint16_t,
		    of_socket_address_t, id, id) =
		    (void (*)(id, SEL, OFString *, uint16_t,
		    of_socket_address_t, id, id))
		    [_target methodForSelector: _selector];

		func(_target, _selector, _host, _port, _address, _context,
		    _exception);
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

- (id)main
{
	void *pool = objc_autoreleasePoolPush();

	@try {
		[OFUDPSocket resolveAddressForHost: _host
					      port: _port
					   address: &_address];
	} @catch (id e) {
		_exception = e;
	}

	[self performSelector: @selector(didResolve)
		     onThread: _sourceThread
		waitUntilDone: false];

	objc_autoreleasePoolPop(pool);

	return nil;
}
@end
#endif

@implementation OFUDPSocket
+ (void)initialize
{
	if (self != [OFUDPSocket class])
		return;

	if (!of_socket_init())
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}

+ (instancetype)socket
{
	return [[[self alloc] init] autorelease];
}

+ (void)resolveAddressForHost: (OFString *)host
			 port: (uint16_t)port
		      address: (of_socket_address_t *)address
{
	of_resolver_result_t **results =
	    of_resolve_host(host, port, SOCK_DGRAM);

	assert(results[0]->addressLength <=
	    (socklen_t)sizeof(address->sockaddr));

	memcpy(&address->sockaddr, results[0]->address,
	    results[0]->addressLength);
	address->length = results[0]->addressLength;

	switch (results[0]->address->sa_family) {
	case AF_INET:
		address->family = OF_SOCKET_ADDRESS_FAMILY_IPV4;
		break;
#ifdef OF_HAVE_IPV6
	case AF_INET6:
		address->family = OF_SOCKET_ADDRESS_FAMILY_IPV6;
		break;
#endif
	default:
		address->family = OF_SOCKET_ADDRESS_FAMILY_UNKNOWN;
		break;
	}

	of_resolver_free(results);
}

#ifdef OF_HAVE_THREADS
+ (void)asyncResolveAddressForHost: (OFString *)host
			      port: (uint16_t)port
			    target: (id)target
			  selector: (SEL)selector
			   context: (id)context
{
	void *pool = objc_autoreleasePoolPush();

	[[[[OFUDPSocket_ResolveThread alloc]
	    initWithSourceThread: [OFThread currentThread]
			    host: host
			    port: port
			  target: target
			selector: selector
			 context: context] autorelease] start];

	objc_autoreleasePoolPop(pool);
}

# ifdef OF_HAVE_BLOCKS
+ (void)asyncResolveAddressForHost: (OFString *)host
			      port: (uint16_t)port
			     block: (of_udp_socket_async_resolve_block_t)block
{
	void *pool = objc_autoreleasePoolPush();

	[[[[OFUDPSocket_ResolveThread alloc]
	    initWithSourceThread: [OFThread currentThread]
			    host: host
			    port: port
			   block: block] autorelease] start];

	objc_autoreleasePoolPop(pool);
}
# endif
#endif

- (instancetype)init
{
	self = [super init];

	_socket = INVALID_SOCKET;
	_blocking = true;








|
>
|
<
|
|
>

>



>








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







22
23
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48










































































































































49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65





































































66
67
68
69
70
71
72
#include <string.h>

#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif

#import "OFUDPSocket.h"
#import "OFUDPSocket+Private.h"
#import "OFDNSResolver.h"
#import "OFData.h"

#import "OFRunLoop+Private.h"
#import "OFRunLoop.h"
#import "OFThread.h"

#import "OFAlreadyConnectedException.h"
#import "OFBindFailedException.h"
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFNotOpenException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFSetOptionFailedException.h"
#import "OFWriteFailedException.h"

#import "socket.h"
#import "socket_helpers.h"











































































































































@implementation OFUDPSocket
+ (void)initialize
{
	if (self != [OFUDPSocket class])
		return;

	if (!of_socket_init())
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}

+ (instancetype)socket
{
	return [[[self alloc] init] autorelease];
}






































































- (instancetype)init
{
	self = [super init];

	_socket = INVALID_SOCKET;
	_blocking = true;

324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347

348
349
350
351
352

353
354
355
356
357
358
359
360
361
362
363
364
365





























366
367
368
369
370


371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410


411


412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454










455
456
457
458


459
460
461
462
























463
464
465
466
467
468
469

	_blocking = enable;
#else
	OF_UNRECOGNIZED_SELECTOR
#endif
}

- (uint16_t)bindToHost: (OFString *)host
		  port: (uint16_t)port
{
	of_resolver_result_t **results;
#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
	of_socket_address_t address;
#endif

	results = of_resolve_host(host, port, SOCK_DGRAM);
	@try {
#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
		int flags;
#endif

		if ((_socket = socket(results[0]->family,
		    results[0]->type | SOCK_CLOEXEC,
		    results[0]->protocol)) == INVALID_SOCKET)

			@throw [OFBindFailedException
			    exceptionWithHost: host
					 port: port
				       socket: self
					errNo: of_socket_errno()];


		_blocking = true;

#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
		if ((flags = fcntl(_socket, F_GETFD, 0)) != -1)
			fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
#endif

#if defined(OF_WII) || defined(OF_NINTENDO_3DS)
		if (port != 0) {
#endif
			if (bind(_socket, results[0]->address,
			    results[0]->addressLength) != 0) {





























				int errNo = of_socket_errno();

				closesocket(_socket);
				_socket = INVALID_SOCKET;



				@throw [OFBindFailedException
				    exceptionWithHost: host
						 port: port
					       socket: self
						errNo: errNo];
			}
#if defined(OF_WII) || defined(OF_NINTENDO_3DS)
		} else {
			for (;;) {
				uint16_t rnd = 0;
				int ret;

				while (rnd < 1024)
					rnd = (uint16_t)rand();

				switch (results[0]->family) {
				case AF_INET:
					((struct sockaddr_in *)
					    results[0]->address)->sin_port =
					    OF_BSWAP16_IF_LE(rnd);
					break;
# ifdef OF_HAVE_IPV6
				case AF_INET6:
					((struct sockaddr_in6 *)
					    results[0]->address)->sin6_port =
					    OF_BSWAP16_IF_LE(rnd);
					break;
# endif
				default:
					@throw [OFInvalidArgumentException
					    exception];
				}

				ret = bind(_socket, results[0]->address,
				    results[0]->addressLength);

				if (ret == 0) {
					port = rnd;
					break;
				}





				if (of_socket_errno() != EADDRINUSE) {
					int errNo = of_socket_errno();

					closesocket(_socket);
					_socket = INVALID_SOCKET;

					@throw [OFBindFailedException
					    exceptionWithHost: host
							 port: port
						       socket: self
							errNo: errNo];
				}
			}
		}
#endif
	} @finally {
		of_resolver_free(results);
	}

	if (port > 0)
		return port;

#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
	address.length = (socklen_t)sizeof(address.sockaddr);
	if (of_getsockname(_socket, &address.sockaddr.sockaddr,
	    &address.length) != 0) {
		int errNo = of_socket_errno();

		closesocket(_socket);
		_socket = INVALID_SOCKET;

		@throw [OFBindFailedException exceptionWithHost: host
							   port: port
							 socket: self
							  errNo: errNo];
	}

	if (address.sockaddr.sockaddr.sa_family == AF_INET)
		return OF_BSWAP16_IF_LE(address.sockaddr.in.sin_port);
# ifdef OF_HAVE_IPV6
	if (address.sockaddr.sockaddr.sa_family == AF_INET6)
		return OF_BSWAP16_IF_LE(address.sockaddr.in6.sin6_port);
# endif










#endif

	closesocket(_socket);
	_socket = INVALID_SOCKET;


	@throw [OFBindFailedException exceptionWithHost: host
						   port: port
						 socket: self
						  errNo: EAFNOSUPPORT];
























}

- (size_t)receiveIntoBuffer: (void *)buffer
		     length: (size_t)length
		     sender: (of_socket_address_t *)sender
{
	ssize_t ret;







<
|

<
<
<
<
|
|
|

|


|
<
|
>
|
|
|
|
|
>

|


|
|



|

|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>






<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
|
<
<

|
|
<
|
>
>

>
>
|
|

|
|

<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<






|
|

|
|

>
>
>
>
>
>
>
>
>
>




>
>



|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







120
121
122
123
124
125
126

127
128




129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199





200


201












202



203
204


205
206
207

208
209
210
211
212
213
214
215
216
217
218
219












220












221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283

	_blocking = enable;
#else
	OF_UNRECOGNIZED_SELECTOR
#endif
}


- (uint16_t)of_bindToAddress: (of_socket_address_t *)address
{




	void *pool = objc_autoreleasePoolPush();
	OFString *host;
	uint16_t port;
#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
	int flags;
#endif

	if ((_socket = socket(address->sockaddr.sockaddr.sa_family,

	    SOCK_DGRAM | SOCK_CLOEXEC, 0)) == INVALID_SOCKET) {
		host = of_socket_address_ip_string(address, &port);
		@throw [OFBindFailedException
		    exceptionWithHost: host
				 port: port
			       socket: self
				errNo: of_socket_errno()];
	}

	_blocking = true;

#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
	if ((flags = fcntl(_socket, F_GETFD, 0)) != -1)
		fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
#endif

#if defined(OF_WII) || defined(OF_NINTENDO_3DS)
	if (port != 0) {
#endif
		if (bind(_socket, &address->sockaddr.sockaddr,
		    address->length) != 0) {
			int errNo = of_socket_errno();

			closesocket(_socket);
			_socket = INVALID_SOCKET;

			host = of_socket_address_ip_string(address, &port);
			@throw [OFBindFailedException exceptionWithHost: host
								   port: port
								 socket: self
								  errNo: errNo];
		}
#if defined(OF_WII) || defined(OF_NINTENDO_3DS)
	} else {
		for (;;) {
			uint16_t rnd = 0;
			int ret;

			while (rnd < 1024)
				rnd = (uint16_t)rand();

			of_socket_address_set_port(address, rnd);

			if ((ret = bind(_socket, &address->sockaddr.sockaddr,
			    address->length)) == 0) {
				port = rnd;
				break;
			}

			if (of_socket_errno() != EADDRINUSE) {
				int errNo = of_socket_errno();

				closesocket(_socket);
				_socket = INVALID_SOCKET;

				host = of_socket_address_ip_string(
				    address, &port);
				@throw [OFBindFailedException
				    exceptionWithHost: host
						 port: port
					       socket: self
						errNo: errNo];
			}





		}


	}












#endif




	objc_autoreleasePoolPop(pool);



	if ((port = of_socket_address_get_port(address)) > 0)
		return port;


#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
	memset(address, 0, sizeof(*address));

	address->length = (socklen_t)sizeof(address->sockaddr);
	if (of_getsockname(_socket, &address->sockaddr.sockaddr,
	    &address->length) != 0) {
		int errNo = of_socket_errno();

		closesocket(_socket);
		_socket = INVALID_SOCKET;













		host = of_socket_address_ip_string(address, &port);












		@throw [OFBindFailedException exceptionWithHost: host
							   port: port
							 socket: self
							  errNo: errNo];
	}

	if (address->sockaddr.sockaddr.sa_family == AF_INET)
		return OF_BSWAP16_IF_LE(address->sockaddr.in.sin_port);
# ifdef OF_HAVE_IPV6
	else if (address->sockaddr.sockaddr.sa_family == AF_INET6)
		return OF_BSWAP16_IF_LE(address->sockaddr.in6.sin6_port);
# endif
	else {
		closesocket(_socket);
		_socket = INVALID_SOCKET;

		host = of_socket_address_ip_string(address, &port);
		@throw [OFBindFailedException exceptionWithHost: host
							   port: port
							 socket: self
							  errNo: EAFNOSUPPORT];
	}
#endif

	closesocket(_socket);
	_socket = INVALID_SOCKET;

	host = of_socket_address_ip_string(address, &port);
	@throw [OFBindFailedException exceptionWithHost: host
						   port: port
						 socket: self
						  errNo: EADDRNOTAVAIL];
}

- (uint16_t)bindToHost: (OFString *)host
		  port: (uint16_t)port
{
	void *pool = objc_autoreleasePoolPush();
	OFData *socketAddresses;
	of_socket_address_t address;

	if (_socket != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException exceptionWithSocket: self];

	socketAddresses = [[OFThread DNSResolver]
	    resolveSocketAddressesForHost: host
			    addressFamily: OF_SOCKET_ADDRESS_FAMILY_ANY];

	address = *(of_socket_address_t *)[socketAddresses itemAtIndex: 0];
	of_socket_address_set_port(&address, port);

	port = [self of_bindToAddress: &address];

	objc_autoreleasePoolPop(pool);

	return port;
}

- (size_t)receiveIntoBuffer: (void *)buffer
		     length: (size_t)length
		     sender: (of_socket_address_t *)sender
{
	ssize_t ret;

Modified src/ObjFW.h from [3fac06979c] to [ee89e1ae2e].

239
240
241
242
243
244
245
246
247
248
249
250
251
#import "base64.h"
#import "crc16.h"
#import "crc32.h"
#import "huffman_tree.h"
#import "instance.h"
#import "of_asprintf.h"
#import "of_strptime.h"
#ifdef OF_HAVE_SOCKETS
# import "resolver.h"
#endif
#import "pbkdf2.h"
#import "scrypt.h"
#import "unicode.h"







<
<
<



239
240
241
242
243
244
245



246
247
248
#import "base64.h"
#import "crc16.h"
#import "crc32.h"
#import "huffman_tree.h"
#import "instance.h"
#import "of_asprintf.h"
#import "of_strptime.h"



#import "pbkdf2.h"
#import "scrypt.h"
#import "unicode.h"

Deleted src/resolver.h version [8e4bcb1595].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
 *               2018
 *   Jonathan Schleifer <js@heap.zone>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFString.h"

#import "socket.h"

OF_ASSUME_NONNULL_BEGIN

/*! @file */

/*!
 * @struct of_resolver_result_t resolver.h ObjFW/resolver.h
 *
 * @brief A struct representing one result from the resolver.
 */
typedef struct {
	int family, type, protocol;
	struct sockaddr *address;
	socklen_t addressLength;
	void *private_;
} of_resolver_result_t;

#ifdef __cplusplus
extern "C" {
#endif
/*!
 * @brief Resolves the specified host.
 *
 * @param host The host to resolve
 * @param port The port that should be inserted into the resulting address
 *	       struct
 * @param protocol The protocol that should be inserted into the resulting
 *		   address struct
 *
 * @return An array of results. The list is terminated by NULL and should be
 *	   freed after use.
 */
extern of_resolver_result_t *_Nullable *_Nonnull of_resolve_host(OFString *host,
    uint16_t port, int protocol);

/*!
 * @brief Frees the results returned by @ref of_resolve_host.
 *
 * @param results The results returned by @ref of_resolve_host
 */
extern void of_resolver_free(
    of_resolver_result_t *_Nullable *_Nonnull results);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































Deleted src/resolver.m version [aa220e27b3].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
/*
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
 *               2018
 *   Jonathan Schleifer <js@heap.zone>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#define _WIN32_WINNT 0x0501

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#import "OFString.h"

#import "resolver.h"
#import "macros.h"

#if !defined(HAVE_THREADSAFE_GETADDRINFO) && defined(OF_HAVE_THREADS)
# include "threading.h"
#endif

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"
#if !defined(HAVE_THREADSAFE_GETADDRINFO) && defined(OF_HAVE_THREADS)
# import "OFLockFailedException.h"
# import "OFUnlockFailedException.h"
#endif
#import "OFResolveHostFailedException.h"

#import "socket_helpers.h"

#if !defined(HAVE_THREADSAFE_GETADDRINFO) && defined(OF_HAVE_THREADS)
static of_mutex_t mutex;

OF_CONSTRUCTOR()
{
	if (!of_mutex_new(&mutex))
		@throw [OFInitializationFailedException exception];
}
#endif

of_resolver_result_t **
of_resolve_host(OFString *host, uint16_t port, int type)
{
	of_resolver_result_t **ret, **retIter;
	of_resolver_result_t *results, *resultsIter;
	size_t count;
#ifdef HAVE_GETADDRINFO
	struct addrinfo hints = { 0 }, *res, *res0;
	char portCString[7];

	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = type;
	hints.ai_flags = AI_NUMERICSERV;
	snprintf(portCString, 7, "%" PRIu16, port);

# if !defined(HAVE_THREADSAFE_GETADDRINFO) && defined(OF_HAVE_THREADS)
	if (!of_mutex_lock(&mutex))
		@throw [OFLockFailedException exception];

	@try {
# endif
		if (getaddrinfo([host UTF8String], portCString, &hints,
		    &res0) != 0)
			@throw [OFResolveHostFailedException
			    exceptionWithHost: host
				  recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN
				   recordType: 0
					error: OF_DNS_RESOLVER_ERROR_UNKNOWN];

		count = 0;
		for (res = res0; res != NULL; res = res->ai_next)
			count++;

		if (count == 0) {
			freeaddrinfo(res0);
			@throw [OFResolveHostFailedException
			    exceptionWithHost: host
				  recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN
				   recordType: 0
					error: OF_DNS_RESOLVER_ERROR_NO_RESULT];
		}

		if ((ret = calloc(count + 1, sizeof(*ret))) == NULL) {
			freeaddrinfo(res0);
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: (count + 1) *
							sizeof(*ret)];
		}

		if ((results = malloc(count * sizeof(*results))) == NULL) {
			freeaddrinfo(res0);
			free(ret);
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: count *
							sizeof(*results)];
		}

		for (retIter = ret, resultsIter = results, res = res0;
		    res != NULL; retIter++, resultsIter++, res = res->ai_next) {
			resultsIter->family = res->ai_family;
			resultsIter->type = res->ai_socktype;
			resultsIter->protocol = res->ai_protocol;
			resultsIter->address = res->ai_addr;
			resultsIter->addressLength = (socklen_t)res->ai_addrlen;

			*retIter = resultsIter;
		}
		*retIter = NULL;

		ret[0]->private_ = res0;
# if !defined(HAVE_THREADSAFE_GETADDRINFO) && defined(OF_HAVE_THREADS)
	} @finally {
		if (!of_mutex_unlock(&mutex))
			@throw [OFUnlockFailedException exception];
	}
# endif
#else
# ifdef OF_HAVE_THREADS
	if (!of_mutex_lock(&mutex))
		@throw [OFLockFailedException exception];

	@try {
# endif
		in_addr_t s_addr;
		struct hostent *he;
		char **ip;
		struct sockaddr_in *addrs, *addrsIter;

		/*
		 * If the host is an IP address, don't try resolving it. On the
		 * Wii for example, the resolver will return an error if you
		 * specify an IP address.
		 */
		if ((s_addr = inet_addr((const void *)[host UTF8String])) !=
		    INADDR_NONE) {
			of_resolver_result_t *tmp;
			struct sockaddr_in *addr;

			if ((ret = calloc(2, sizeof(*ret))) == NULL)
				@throw [OFOutOfMemoryException
				    exceptionWithRequestedSize: 2 *
								sizeof(*ret)];

			if ((tmp = malloc(sizeof(*tmp))) == NULL) {
				free(ret);
				@throw [OFOutOfMemoryException
				    exceptionWithRequestedSize: sizeof(*tmp)];
			}

			if ((addr = calloc(1, sizeof(*addr))) == NULL) {
				free(ret);
				free(tmp);
				@throw [OFOutOfMemoryException
				    exceptionWithRequestedSize: sizeof(*addr)];
			}

#ifdef OF_WII
			addr->sin_len = 8;
#endif
			addr->sin_family = AF_INET;
			addr->sin_port = OF_BSWAP16_IF_LE(port);
			addr->sin_addr.s_addr = s_addr;

			tmp->family = AF_INET;
			tmp->type = type;
			tmp->protocol = 0;
			tmp->address = (struct sockaddr *)addr;
#ifndef OF_WII
			tmp->addressLength = sizeof(*addr);
#else
			tmp->addressLength = 8;
#endif

			ret[0] = tmp;
			ret[1] = NULL;

			return ret;
		}

		if ((he = gethostbyname((const void *)[host UTF8String])) ==
		    NULL || he->h_addrtype != AF_INET)
			@throw [OFResolveHostFailedException
			    exceptionWithHost: host
				  recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN
				   recordType: 0
					error: OF_DNS_RESOLVER_ERROR_UNKNOWN];

		count = 0;
		for (ip = (char **)he->h_addr_list; *ip != NULL; ip++)
			count++;

		if (count == 0)
			@throw [OFResolveHostFailedException
			    exceptionWithHost: host
				  recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN
				   recordType: 0
					error: OF_DNS_RESOLVER_ERROR_NO_RESULT];

		if ((ret = calloc(count + 1, sizeof(*ret))) == NULL)
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: (count + 1) *
							sizeof(*ret)];

		if ((results = malloc(count * sizeof(*results))) == NULL) {
			free(ret);
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: count *
							sizeof(*results)];
		}

		if ((addrs = calloc(count, sizeof(*addrs))) == NULL) {
			free(ret);
			free(results);
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: count * sizeof(*addrs)];
		}

		for (retIter = ret, resultsIter = results, addrsIter = addrs,
		    ip = (char **)he->h_addr_list; *ip != NULL;
		    retIter++, resultsIter++, addrsIter++, ip++) {
			addrsIter->sin_family = he->h_addrtype;
			addrsIter->sin_port = OF_BSWAP16_IF_LE(port);

			if ((size_t)he->h_length >
			    sizeof(addrsIter->sin_addr.s_addr))
				@throw [OFOutOfRangeException exception];

			memcpy(&addrsIter->sin_addr.s_addr, *ip, he->h_length);

			resultsIter->family = he->h_addrtype;
			resultsIter->type = type;
			resultsIter->protocol = 0;
			resultsIter->address = (struct sockaddr *)addrsIter;
			resultsIter->addressLength = sizeof(*addrsIter);

			*retIter = resultsIter;
		}
# ifdef OF_HAVE_THREADS
	} @finally {
		if (!of_mutex_unlock(&mutex))
			@throw [OFUnlockFailedException exception];
	}
# endif
#endif

	return ret;
}

void
of_resolver_free(of_resolver_result_t **results)
{
#ifdef HAVE_GETADDRINFO
	freeaddrinfo(results[0]->private_);
#else
	free(results[0]->address);
#endif
	free(results[0]);
	free(results);
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































Modified src/socket.h from [2431bf7b16] to [949bb8ad8d].

203
204
205
206
207
208
209










210
211
212
213
214
 *	  the address family used.
 *
 * @param address The address on which to set the port
 * @param port The port to set on the address
 */
extern void of_socket_address_set_port(of_socket_address_t *_Nonnull address,
    uint16_t port);










#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END







>
>
>
>
>
>
>
>
>
>





203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
 *	  the address family used.
 *
 * @param address The address on which to set the port
 * @param port The port to set on the address
 */
extern void of_socket_address_set_port(of_socket_address_t *_Nonnull address,
    uint16_t port);

/*!
 * @brief Returns the port of the specified of_socket_address_t, independent of
 *	  the address family used.
 *
 * @param address The address on which to get the port
 * @return The port of the address
 */
extern uint16_t of_socket_address_get_port(
    const of_socket_address_t *_Nonnull address);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/socket.m from [72b93f58cf] to [00380c738c].

604
605
606
607
608
609
610













	case OF_SOCKET_ADDRESS_FAMILY_IPV6:
		address->sockaddr.in6.sin6_port = OF_BSWAP16_IF_LE(port);
		break;
	default:
		@throw [OFInvalidArgumentException exception];
	}
}




















>
>
>
>
>
>
>
>
>
>
>
>
>
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
	case OF_SOCKET_ADDRESS_FAMILY_IPV6:
		address->sockaddr.in6.sin6_port = OF_BSWAP16_IF_LE(port);
		break;
	default:
		@throw [OFInvalidArgumentException exception];
	}
}

uint16_t
of_socket_address_get_port(const of_socket_address_t *address)
{
	switch (address->family) {
	case OF_SOCKET_ADDRESS_FAMILY_IPV4:
		return OF_BSWAP16_IF_LE(address->sockaddr.in.sin_port);
	case OF_SOCKET_ADDRESS_FAMILY_IPV6:
		return OF_BSWAP16_IF_LE(address->sockaddr.in6.sin6_port);
	default:
		@throw [OFInvalidArgumentException exception];
	}
}

Modified src/socket_helpers.h from [9196eb16cc] to [0b9f3f23ab].

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

#include "socket.h"

#ifndef INVALID_SOCKET
# define INVALID_SOCKET -1
#endif

#ifdef HAVE_GETADDRINFO
# ifndef AI_NUMERICSERV
#  define AI_NUMERICSERV 0
# endif
# ifndef AI_NUMERICHOST
#  define AI_NUMERICHOST 0
# endif
#endif

#ifndef INADDR_NONE
# define INADDR_NONE ((in_addr_t)-1)
#endif

#ifndef SOMAXCONN
/*
 * Use 16 as everything > 17 fails on Nintendo 3DS and 16 is a less arbitrary







<
<
<
<
<
<
<
<
<







28
29
30
31
32
33
34









35
36
37
38
39
40
41

#include "socket.h"

#ifndef INVALID_SOCKET
# define INVALID_SOCKET -1
#endif










#ifndef INADDR_NONE
# define INADDR_NONE ((in_addr_t)-1)
#endif

#ifndef SOMAXCONN
/*
 * Use 16 as everything > 17 fails on Nintendo 3DS and 16 is a less arbitrary
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#ifdef OF_WII
# define accept(sock, addr, addrlen) net_accept(sock, addr, addrlen)
# define bind(sock, addr, addrlen) net_bind(sock, addr, addrlen)
# define closesocket(sock) net_close(sock)
# define connect(sock, addr, addrlen) \
    net_connect(sock, (struct sockaddr *)addr, addrlen)
# define fcntl(fd, cmd, flags) net_fcntl(fd, cmd, flags)
# define gethostbyname(name) net_gethostbyname(name)
# define getsockopt(sock, level, name, value, len) \
    net_getsockopt(sock, level, name, value, len)
# define h_errno 0
# define hstrerror(err) "unknown (no hstrerror)"
# define listen(sock, backlog) net_listen(sock, backlog)
# define poll(fds, nfds, timeout) net_poll(fds, nfds, timeout)
# define recv(sock, buf, len, flags) net_recv(sock, buf, len, flags)







<







64
65
66
67
68
69
70

71
72
73
74
75
76
77
#ifdef OF_WII
# define accept(sock, addr, addrlen) net_accept(sock, addr, addrlen)
# define bind(sock, addr, addrlen) net_bind(sock, addr, addrlen)
# define closesocket(sock) net_close(sock)
# define connect(sock, addr, addrlen) \
    net_connect(sock, (struct sockaddr *)addr, addrlen)
# define fcntl(fd, cmd, flags) net_fcntl(fd, cmd, flags)

# define getsockopt(sock, level, name, value, len) \
    net_getsockopt(sock, level, name, value, len)
# define h_errno 0
# define hstrerror(err) "unknown (no hstrerror)"
# define listen(sock, backlog) net_listen(sock, backlog)
# define poll(fds, nfds, timeout) net_poll(fds, nfds, timeout)
# define recv(sock, buf, len, flags) net_recv(sock, buf, len, flags)

Modified tests/OFUDPSocketTests.m from [1bbed581ea] to [b4dbd2c54c].

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

	TEST(@"+[socket]", (sock = [OFUDPSocket socket]))

	TEST(@"-[bindToHost:port:]",
	    (port1 = [sock bindToHost: @"127.0.0.1"
				 port: 0]))

	TEST(@"+[resolveAddressForHost:port:address:]",
	    R([OFUDPSocket resolveAddressForHost: @"127.0.0.1"
					    port: port1
					 address: &addr1]))

	TEST(@"-[sendBuffer:length:receiver:]",
	    R([sock sendBuffer: "Hello"
			length: 6
		      receiver: &addr1]))

	TEST(@"-[receiveIntoBuffer:length:sender:]",
	    [sock receiveIntoBuffer: buf
			     length: 6
			     sender: &addr2] == 6 &&
	    !memcmp(buf, "Hello", 6) &&
	    (host = of_socket_address_ip_string(&addr2, &port2)) &&
	    [host isEqual: @"127.0.0.1"] && port2 == port1)

	[OFUDPSocket resolveAddressForHost: @"127.0.0.1"
				      port: port1 + 1
				   address: &addr3];

	/*
	 * TODO: Move those tests elsewhere as soon as the DNS resolving part
	 *	 is no longer in OFUDPSocket.
	 */
	TEST(@"of_socket_address_equal()",
	    of_socket_address_equal(&addr1, &addr2) &&







<
|
<
<














|
<
<







39
40
41
42
43
44
45

46


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61


62
63
64
65
66
67
68

	TEST(@"+[socket]", (sock = [OFUDPSocket socket]))

	TEST(@"-[bindToHost:port:]",
	    (port1 = [sock bindToHost: @"127.0.0.1"
				 port: 0]))


	addr1 = of_socket_address_parse_ip(@"127.0.0.1", port1);



	TEST(@"-[sendBuffer:length:receiver:]",
	    R([sock sendBuffer: "Hello"
			length: 6
		      receiver: &addr1]))

	TEST(@"-[receiveIntoBuffer:length:sender:]",
	    [sock receiveIntoBuffer: buf
			     length: 6
			     sender: &addr2] == 6 &&
	    !memcmp(buf, "Hello", 6) &&
	    (host = of_socket_address_ip_string(&addr2, &port2)) &&
	    [host isEqual: @"127.0.0.1"] && port2 == port1)

	addr3 = of_socket_address_parse_ip(@"127.0.0.1", port1 + 1);



	/*
	 * TODO: Move those tests elsewhere as soon as the DNS resolving part
	 *	 is no longer in OFUDPSocket.
	 */
	TEST(@"of_socket_address_equal()",
	    of_socket_address_equal(&addr1, &addr2) &&