ObjFW  Check-in [d1c9ed8498]

Overview
Comment:Merge trunk into branch "appletalk"
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | appletalk
Files: files | file ages | folders
SHA3-256: d1c9ed8498ac3cfce69b94ba6fb689503eab5beb362d2b093f84c0bbcb4d113b
User & Date: js on 2022-10-22 18:46:25
Other Links: branch diff | manifest | tags
Context
2022-10-22
18:49
OFDDPSocket: Fix minor documentation mistake check-in: 4fa1ac90d7 user: js tags: appletalk
18:46
Merge trunk into branch "appletalk" check-in: d1c9ed8498 user: js tags: appletalk
18:41
OFSocket: Don't combine port for IP and IPX check-in: a54730b88f user: js tags: trunk
18:32
OFDDPSocket: Bind with network, node & port check-in: 707206e796 user: js tags: appletalk
Changes

Modified src/OFIPSocketAsyncConnector.m from [11edaa9dd3] to [ca32b06485].

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

- (void)tryNextAddressWithRunLoopMode: (OFRunLoopMode)runLoopMode
{
	OFSocketAddress address = *(const OFSocketAddress *)
	    [_socketAddresses itemAtIndex: _socketAddressesIndex++];
	int errNo;

	OFSocketAddressSetPort(&address, _port);

	if (![_socket of_createSocketForAddress: &address errNo: &errNo]) {
		if (_socketAddressesIndex >= _socketAddresses.count) {
			_exception = [[OFConnectIPSocketFailedException alloc]
			    initWithHost: _host
				    port: _port
				  socket: _socket







|







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

- (void)tryNextAddressWithRunLoopMode: (OFRunLoopMode)runLoopMode
{
	OFSocketAddress address = *(const OFSocketAddress *)
	    [_socketAddresses itemAtIndex: _socketAddressesIndex++];
	int errNo;

	OFSocketAddressSetIPPort(&address, _port);

	if (![_socket of_createSocketForAddress: &address errNo: &errNo]) {
		if (_socketAddressesIndex >= _socketAddresses.count) {
			_exception = [[OFConnectIPSocketFailedException alloc]
			    initWithHost: _host
				    port: _port
				  socket: _socket

Modified src/OFSocket.h from [24521aefe5] to [990896e9f7].

278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
 * @param address The address to convert to a string
 * @return The address as an IP string
 */
extern OFString *_Nonnull OFSocketAddressString(
    const OFSocketAddress *_Nonnull address);

/**
 * @brief Sets the port of the specified @ref OFSocketAddress, independent of
 *	  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 OFSocketAddressSetPort(OFSocketAddress *_Nonnull address,
    uint16_t port);

/**
 * @brief Returns the port of the specified @ref OFSocketAddress, 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 OFSocketAddressPort(const OFSocketAddress *_Nonnull address);

/**
 * @brief Gets the UNIX socket path of the specified @ref OFSocketAddress.
 *
 * @param address The address on which to get the UNIX socket path
 * @return The UNIX socket path
 */







|
<




|



|
<




|







278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
293
294

295
296
297
298
299
300
301
302
303
304
305
306
 * @param address The address to convert to a string
 * @return The address as an IP string
 */
extern OFString *_Nonnull OFSocketAddressString(
    const OFSocketAddress *_Nonnull address);

/**
 * @brief Sets the IP port of the specified @ref OFSocketAddress.

 *
 * @param address The address on which to set the port
 * @param port The port to set on the address
 */
extern void OFSocketAddressSetIPPort(OFSocketAddress *_Nonnull address,
    uint16_t port);

/**
 * @brief Returns the IP port of the specified @ref OFSocketAddress.

 *
 * @param address The address on which to get the port
 * @return The port of the address
 */
extern uint16_t OFSocketAddressIPPort(const OFSocketAddress *_Nonnull address);

/**
 * @brief Gets the UNIX socket path of the specified @ref OFSocketAddress.
 *
 * @param address The address on which to get the UNIX socket path
 * @return The UNIX socket path
 */
341
342
343
344
345
346
347

















348
349
350
351
352
353
354
 *
 * @param address The address on which to get the IPX node
 * @param node A byte array to store the IPX node of the address
 */
extern void OFSocketAddressGetIPXNode(const OFSocketAddress *_Nonnull address,
    unsigned char node[_Nonnull IPX_NODE_LEN]);


















/**
 * @brief Sets the AppleTalk network of the specified @ref OFSocketAddress.
 *
 * @param address The address on which to set the AppleTalk network
 * @param network The AppleTalk network to set on the address
 */
extern void OFSocketAddressSetAppleTalkNetwork(







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







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
 *
 * @param address The address on which to get the IPX node
 * @param node A byte array to store the IPX node of the address
 */
extern void OFSocketAddressGetIPXNode(const OFSocketAddress *_Nonnull address,
    unsigned char node[_Nonnull IPX_NODE_LEN]);

/**
 * @brief Sets the IPX port of the specified @ref OFSocketAddress.
 *
 * @param address The address on which to set the port
 * @param port The port to set on the address
 */
extern void OFSocketAddressSetIPXPort(OFSocketAddress *_Nonnull address,
    uint16_t port);

/**
 * @brief Returns the IPX port of the specified @ref OFSocketAddress.
 *
 * @param address The address on which to get the port
 * @return The port of the address
 */
extern uint16_t OFSocketAddressIPXPort(const OFSocketAddress *_Nonnull address);

/**
 * @brief Sets the AppleTalk network of the specified @ref OFSocketAddress.
 *
 * @param address The address on which to set the AppleTalk network
 * @param network The AppleTalk network to set on the address
 */
extern void OFSocketAddressSetAppleTalkNetwork(
377
378
379
380
381
382
383


















384
385
386
387
388
389
390
 *
 * @param address The address on which to get the AppleTalk node
 * @return The AppleTalk node of the address
 */
extern uint8_t OFSocketAddressAppleTalkNode(
    const OFSocketAddress *_Nonnull address);



















extern bool OFSocketInit(void);
#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
extern void OFSocketDeinit(void);
#endif
extern int OFSocketErrNo(void);
#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
extern int OFGetSockName(OFSocketHandle sock, struct sockaddr *restrict addr,







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







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
 *
 * @param address The address on which to get the AppleTalk node
 * @return The AppleTalk node of the address
 */
extern uint8_t OFSocketAddressAppleTalkNode(
    const OFSocketAddress *_Nonnull address);

/**
 * @brief Sets the AppleTalk port of the specified @ref OFSocketAddress.
 *
 * @param address The address on which to set the port
 * @param port The port to set on the address
 */
extern void OFSocketAddressSetAppleTalkPort(OFSocketAddress *_Nonnull address,
    uint8_t port);

/**
 * @brief Returns the AppleTalk port of the specified @ref OFSocketAddress.
 *
 * @param address The address on which to get the port
 * @return The port of the address
 */
extern uint8_t OFSocketAddressAppleTalkPort(
    const OFSocketAddress *_Nonnull address);

extern bool OFSocketInit(void);
#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
extern void OFSocketDeinit(void);
#endif
extern int OFSocketErrNo(void);
#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
extern int OFGetSockName(OFSocketHandle sock, struct sockaddr *restrict addr,

Modified src/OFSocket.m from [60f126f761] to [4fc1cbbf22].

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
		return IPv6String(address);
	default:
		@throw [OFInvalidArgumentException exception];
	}
}

void
OFSocketAddressSetPort(OFSocketAddress *address, uint16_t port)
{
	switch (address->family) {
	case OFSocketAddressFamilyIPv4:
		address->sockaddr.in.sin_port = OFToBigEndian16(port);
		break;
	case OFSocketAddressFamilyIPv6:
		address->sockaddr.in6.sin6_port = OFToBigEndian16(port);
		break;
	case OFSocketAddressFamilyIPX:
		address->sockaddr.ipx.sipx_port = OFToBigEndian16(port);
		break;
	case OFSocketAddressFamilyAppleTalk:
		if (port > UINT8_MAX)
			@throw [OFOutOfRangeException exception];

		address->sockaddr.at.sat_port = (uint8_t)port;
	default:
		@throw [OFInvalidArgumentException exception];
	}
}

uint16_t
OFSocketAddressPort(const OFSocketAddress *address)
{
	switch (address->family) {
	case OFSocketAddressFamilyIPv4:
		return OFFromBigEndian16(address->sockaddr.in.sin_port);
	case OFSocketAddressFamilyIPv6:
		return OFFromBigEndian16(address->sockaddr.in6.sin6_port);
	case OFSocketAddressFamilyIPX:
		return OFFromBigEndian16(address->sockaddr.ipx.sipx_port);
	case OFSocketAddressFamilyAppleTalk:
		return address->sockaddr.at.sat_port;
	default:
		@throw [OFInvalidArgumentException exception];
	}
}

OFString *
OFSocketAddressUNIXPath(const OFSocketAddress *_Nonnull address)







|








<
<
<
<
<
<
<
<






|






<
<
<
<







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
		return IPv6String(address);
	default:
		@throw [OFInvalidArgumentException exception];
	}
}

void
OFSocketAddressSetIPPort(OFSocketAddress *address, uint16_t port)
{
	switch (address->family) {
	case OFSocketAddressFamilyIPv4:
		address->sockaddr.in.sin_port = OFToBigEndian16(port);
		break;
	case OFSocketAddressFamilyIPv6:
		address->sockaddr.in6.sin6_port = OFToBigEndian16(port);
		break;








	default:
		@throw [OFInvalidArgumentException exception];
	}
}

uint16_t
OFSocketAddressIPPort(const OFSocketAddress *address)
{
	switch (address->family) {
	case OFSocketAddressFamilyIPv4:
		return OFFromBigEndian16(address->sockaddr.in.sin_port);
	case OFSocketAddressFamilyIPv6:
		return OFFromBigEndian16(address->sockaddr.in6.sin6_port);




	default:
		@throw [OFInvalidArgumentException exception];
	}
}

OFString *
OFSocketAddressUNIXPath(const OFSocketAddress *_Nonnull address)
985
986
987
988
989
990
991


















992
993
994
995
996
997
998
    unsigned char node[IPX_NODE_LEN])
{
	if (address->family != OFSocketAddressFamilyIPX)
		@throw [OFInvalidArgumentException exception];

	memcpy(node, address->sockaddr.ipx.sipx_node, IPX_NODE_LEN);
}



















void
OFSocketAddressSetAppleTalkNetwork(OFSocketAddress *address, uint16_t network)
{
	if (address->family != OFSocketAddressFamilyAppleTalk)
		@throw [OFInvalidArgumentException exception];








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







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
    unsigned char node[IPX_NODE_LEN])
{
	if (address->family != OFSocketAddressFamilyIPX)
		@throw [OFInvalidArgumentException exception];

	memcpy(node, address->sockaddr.ipx.sipx_node, IPX_NODE_LEN);
}

void
OFSocketAddressSetIPXPort(OFSocketAddress *address, uint16_t port)
{
	if (address->family != OFSocketAddressFamilyIPX)
		@throw [OFInvalidArgumentException exception];

	address->sockaddr.ipx.sipx_port = OFToBigEndian16(port);
}

uint16_t
OFSocketAddressIPXPort(const OFSocketAddress *address)
{
	if (address->family != OFSocketAddressFamilyIPX)
		@throw [OFInvalidArgumentException exception];

	return OFFromBigEndian16(address->sockaddr.ipx.sipx_port);
}

void
OFSocketAddressSetAppleTalkNetwork(OFSocketAddress *address, uint16_t network)
{
	if (address->family != OFSocketAddressFamilyAppleTalk)
		@throw [OFInvalidArgumentException exception];

1021
1022
1023
1024
1025
1026
1027


















OFSocketAddressAppleTalkNode(const OFSocketAddress *address)
{
	if (address->family != OFSocketAddressFamilyAppleTalk)
		@throw [OFInvalidArgumentException exception];

	return address->sockaddr.at.sat_node;
}

























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
OFSocketAddressAppleTalkNode(const OFSocketAddress *address)
{
	if (address->family != OFSocketAddressFamilyAppleTalk)
		@throw [OFInvalidArgumentException exception];

	return address->sockaddr.at.sat_node;
}

void
OFSocketAddressSetAppleTalkPort(OFSocketAddress *address, uint8_t port)
{
	if (address->family != OFSocketAddressFamilyAppleTalk)
		@throw [OFInvalidArgumentException exception];

	address->sockaddr.at.sat_port = port;
}

uint8_t
OFSocketAddressAppleTalkPort(const OFSocketAddress *address)
{
	if (address->family != OFSocketAddressFamilyAppleTalk)
		@throw [OFInvalidArgumentException exception];

	return address->sockaddr.at.sat_port;
}

Modified src/OFTCPSocket.m from [e6378dfef4] to [74ced9f7d1].

307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
								 object: self];

	socketAddresses = [[OFThread DNSResolver]
	    resolveAddressesForHost: host
		      addressFamily: OFSocketAddressFamilyAny];

	address = *(OFSocketAddress *)[socketAddresses itemAtIndex: 0];
	OFSocketAddressSetPort(&address, port);

	if ((_socket = socket(
	    ((struct sockaddr *)&address.sockaddr)->sa_family,
	    SOCK_STREAM | SOCK_CLOEXEC, 0)) == OFInvalidSocketHandle)
		@throw [OFBindIPSocketFailedException
		    exceptionWithHost: host
				 port: port







|







307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
								 object: self];

	socketAddresses = [[OFThread DNSResolver]
	    resolveAddressesForHost: host
		      addressFamily: OFSocketAddressFamilyAny];

	address = *(OFSocketAddress *)[socketAddresses itemAtIndex: 0];
	OFSocketAddressSetIPPort(&address, port);

	if ((_socket = socket(
	    ((struct sockaddr *)&address.sockaddr)->sa_family,
	    SOCK_STREAM | SOCK_CLOEXEC, 0)) == OFInvalidSocketHandle)
		@throw [OFBindIPSocketFailedException
		    exceptionWithHost: host
				 port: port

Modified src/OFUDPSocket.m from [fd8f9dff29] to [f8c53776df].

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
#endif

	if ((_socket = socket(
	    ((struct sockaddr *)&address->sockaddr)->sa_family,
	    SOCK_DGRAM | SOCK_CLOEXEC | extraType, 0)) == OFInvalidSocketHandle)
		@throw [OFBindIPSocketFailedException
		    exceptionWithHost: OFSocketAddressString(address)
				 port: OFSocketAddressPort(address)
			       socket: self
				errNo: OFSocketErrNo()];

	_canBlock = true;

#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
	/* {} needed to avoid warning with Clang 10 if next #if is false. */
	if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) {
		fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
	}
#endif

#if defined(OF_HPUX) || defined(OF_WII) || defined(OF_NINTENDO_3DS)
	if (OFSocketAddressPort(address) != 0) {
#endif
		if (bind(_socket, (struct sockaddr *)&address->sockaddr,
		    address->length) != 0) {
			int errNo = OFSocketErrNo();

			closesocket(_socket);
			_socket = OFInvalidSocketHandle;

			@throw [OFBindIPSocketFailedException
			    exceptionWithHost: OFSocketAddressString(address)
					 port: OFSocketAddressPort(address)
				       socket: self
					errNo: errNo];
		}
#if defined(OF_HPUX) || defined(OF_WII) || defined(OF_NINTENDO_3DS)
	} else {
		for (;;) {
			uint16_t rnd = 0;







|













|










|







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
#endif

	if ((_socket = socket(
	    ((struct sockaddr *)&address->sockaddr)->sa_family,
	    SOCK_DGRAM | SOCK_CLOEXEC | extraType, 0)) == OFInvalidSocketHandle)
		@throw [OFBindIPSocketFailedException
		    exceptionWithHost: OFSocketAddressString(address)
				 port: OFSocketAddressIPPort(address)
			       socket: self
				errNo: OFSocketErrNo()];

	_canBlock = true;

#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
	/* {} needed to avoid warning with Clang 10 if next #if is false. */
	if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) {
		fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
	}
#endif

#if defined(OF_HPUX) || defined(OF_WII) || defined(OF_NINTENDO_3DS)
	if (OFSocketAddressIPPort(address) != 0) {
#endif
		if (bind(_socket, (struct sockaddr *)&address->sockaddr,
		    address->length) != 0) {
			int errNo = OFSocketErrNo();

			closesocket(_socket);
			_socket = OFInvalidSocketHandle;

			@throw [OFBindIPSocketFailedException
			    exceptionWithHost: OFSocketAddressString(address)
					 port: OFSocketAddressIPPort(address)
				       socket: self
					errNo: errNo];
		}
#if defined(OF_HPUX) || defined(OF_WII) || defined(OF_NINTENDO_3DS)
	} else {
		for (;;) {
			uint16_t rnd = 0;
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
			    (struct sockaddr *)&address->sockaddr,
			    address->length)) == 0)
				break;

			if (OFSocketErrNo() != EADDRINUSE) {
				int errNo = OFSocketErrNo();
				OFString *host = OFSocketAddressString(address);
				port = OFSocketAddressPort(address);

				closesocket(_socket);
				_socket = OFInvalidSocketHandle;

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

	objc_autoreleasePoolPop(pool);

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

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

	address->length = (socklen_t)sizeof(address->sockaddr);
	if (OFGetSockName(_socket, (struct sockaddr *)&address->sockaddr,
	    &address->length) != 0) {
		int errNo = OFSocketErrNo();

		closesocket(_socket);
		_socket = OFInvalidSocketHandle;

		@throw [OFBindIPSocketFailedException
		    exceptionWithHost: OFSocketAddressString(address)
				 port: OFSocketAddressPort(address)
			       socket: self
				errNo: errNo];
	}

	switch (((struct sockaddr *)&address->sockaddr)->sa_family) {
	case AF_INET:
		return OFFromBigEndian16(address->sockaddr.in.sin_port);
# ifdef OF_HAVE_IPV6
	case AF_INET6:
		return OFFromBigEndian16(address->sockaddr.in6.sin6_port);
# endif
	default:
		closesocket(_socket);
		_socket = OFInvalidSocketHandle;

		@throw [OFBindIPSocketFailedException
		    exceptionWithHost: OFSocketAddressString(address)
				 port: OFSocketAddressPort(address)
			       socket: self
				errNo: EAFNOSUPPORT];
	}
#else
	closesocket(_socket);
	_socket = OFInvalidSocketHandle;

	@throw [OFBindIPSocketFailedException
	    exceptionWithHost: OFSocketAddressString(address)
			 port: OFSocketAddressPort(address)
		       socket: self
			errNo: EADDRNOTAVAIL];
#endif
}

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

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

	socketAddresses = [[OFThread DNSResolver]
	    resolveAddressesForHost: host
		      addressFamily: OFSocketAddressFamilyAny];

	address = *(OFSocketAddress *)[socketAddresses itemAtIndex: 0];
	OFSocketAddressSetPort(&address, port);

	port = [self of_bindToAddress: &address extraType: 0];

	objc_autoreleasePoolPop(pool);

	return port;
}
@end







|
















|















|

















|









|



















|








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
			    (struct sockaddr *)&address->sockaddr,
			    address->length)) == 0)
				break;

			if (OFSocketErrNo() != EADDRINUSE) {
				int errNo = OFSocketErrNo();
				OFString *host = OFSocketAddressString(address);
				port = OFSocketAddressIPPort(address);

				closesocket(_socket);
				_socket = OFInvalidSocketHandle;

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

	objc_autoreleasePoolPop(pool);

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

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

	address->length = (socklen_t)sizeof(address->sockaddr);
	if (OFGetSockName(_socket, (struct sockaddr *)&address->sockaddr,
	    &address->length) != 0) {
		int errNo = OFSocketErrNo();

		closesocket(_socket);
		_socket = OFInvalidSocketHandle;

		@throw [OFBindIPSocketFailedException
		    exceptionWithHost: OFSocketAddressString(address)
				 port: OFSocketAddressIPPort(address)
			       socket: self
				errNo: errNo];
	}

	switch (((struct sockaddr *)&address->sockaddr)->sa_family) {
	case AF_INET:
		return OFFromBigEndian16(address->sockaddr.in.sin_port);
# ifdef OF_HAVE_IPV6
	case AF_INET6:
		return OFFromBigEndian16(address->sockaddr.in6.sin6_port);
# endif
	default:
		closesocket(_socket);
		_socket = OFInvalidSocketHandle;

		@throw [OFBindIPSocketFailedException
		    exceptionWithHost: OFSocketAddressString(address)
				 port: OFSocketAddressIPPort(address)
			       socket: self
				errNo: EAFNOSUPPORT];
	}
#else
	closesocket(_socket);
	_socket = OFInvalidSocketHandle;

	@throw [OFBindIPSocketFailedException
	    exceptionWithHost: OFSocketAddressString(address)
			 port: OFSocketAddressIPPort(address)
		       socket: self
			errNo: EADDRNOTAVAIL];
#endif
}

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

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

	socketAddresses = [[OFThread DNSResolver]
	    resolveAddressesForHost: host
		      addressFamily: OFSocketAddressFamilyAny];

	address = *(OFSocketAddress *)[socketAddresses itemAtIndex: 0];
	OFSocketAddressSetIPPort(&address, port);

	port = [self of_bindToAddress: &address extraType: 0];

	objc_autoreleasePoolPop(pool);

	return port;
}
@end

Modified tests/OFSPXSocketTests.m from [2398c8daff] to [951eb7a23c].

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

		objc_autoreleasePoolPop(pool);
		return;
	}

	network = OFSocketAddressIPXNetwork(&address1);
	OFSocketAddressGetIPXNode(&address1, node);
	port = OFSocketAddressPort(&address1);

	TEST(@"-[listen]", R([sockServer listen]))

	TEST(@"-[connectToNetwork:node:port:]",
	    R([sockClient connectToNetwork: network node: node port: port]))

	TEST(@"-[accept]", (sockAccepted = [sockServer accept]))







|







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

		objc_autoreleasePoolPop(pool);
		return;
	}

	network = OFSocketAddressIPXNetwork(&address1);
	OFSocketAddressGetIPXNode(&address1, node);
	port = OFSocketAddressIPXPort(&address1);

	TEST(@"-[listen]", R([sockServer listen]))

	TEST(@"-[connectToNetwork:node:port:]",
	    R([sockClient connectToNetwork: network node: node port: port]))

	TEST(@"-[accept]", (sockAccepted = [sockServer accept]))
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
	[sockServer listen];
	[sockServer asyncAccept];

	delegate->_expectedNetwork = network =
	    OFSocketAddressIPXNetwork(&address1);
	OFSocketAddressGetIPXNode(&address1, node);
	memcpy(delegate->_expectedNode, node, IPX_NODE_LEN);
	delegate->_expectedPort = port = OFSocketAddressPort(&address1);

	@try {
		[sockClient asyncConnectToNetwork: network
					     node: node
					     port: port];

		[[OFRunLoop mainRunLoop] runUntilDate:







|







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
	[sockServer listen];
	[sockServer asyncAccept];

	delegate->_expectedNetwork = network =
	    OFSocketAddressIPXNetwork(&address1);
	OFSocketAddressGetIPXNode(&address1, node);
	memcpy(delegate->_expectedNode, node, IPX_NODE_LEN);
	delegate->_expectedPort = port = OFSocketAddressIPXPort(&address1);

	@try {
		[sockClient asyncConnectToNetwork: network
					     node: node
					     port: port];

		[[OFRunLoop mainRunLoop] runUntilDate:

Modified tests/OFSPXStreamSocketTests.m from [5afcf8a434] to [ca6bf9ee77].

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

		objc_autoreleasePoolPop(pool);
		return;
	}

	network = OFSocketAddressIPXNetwork(&address1);
	OFSocketAddressGetIPXNode(&address1, node);
	port = OFSocketAddressPort(&address1);

	TEST(@"-[listen]", R([sockServer listen]))

	TEST(@"-[connectToNetwork:node:port:]",
	    R([sockClient connectToNetwork: network node: node port: port]))

	TEST(@"-[accept]", (sockAccepted = [sockServer accept]))







|







117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

		objc_autoreleasePoolPop(pool);
		return;
	}

	network = OFSocketAddressIPXNetwork(&address1);
	OFSocketAddressGetIPXNode(&address1, node);
	port = OFSocketAddressIPXPort(&address1);

	TEST(@"-[listen]", R([sockServer listen]))

	TEST(@"-[connectToNetwork:node:port:]",
	    R([sockClient connectToNetwork: network node: node port: port]))

	TEST(@"-[accept]", (sockAccepted = [sockServer accept]))
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
	[sockServer listen];
	[sockServer asyncAccept];

	delegate->_expectedNetwork = network =
	    OFSocketAddressIPXNetwork(&address1);
	OFSocketAddressGetIPXNode(&address1, node);
	memcpy(delegate->_expectedNode, node, IPX_NODE_LEN);
	delegate->_expectedPort = port = OFSocketAddressPort(&address1);

	@try {
		[sockClient asyncConnectToNetwork: network
					     node: node
					     port: port];

		[[OFRunLoop mainRunLoop] runUntilDate:







|







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
	[sockServer listen];
	[sockServer asyncAccept];

	delegate->_expectedNetwork = network =
	    OFSocketAddressIPXNetwork(&address1);
	OFSocketAddressGetIPXNode(&address1, node);
	memcpy(delegate->_expectedNode, node, IPX_NODE_LEN);
	delegate->_expectedPort = port = OFSocketAddressIPXPort(&address1);

	@try {
		[sockClient asyncConnectToNetwork: network
					     node: node
					     port: port];

		[[OFRunLoop mainRunLoop] runUntilDate:

Modified tests/OFSocketTests.m from [3d043537f3] to [0766971ff5].

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

	EXPECT_EXCEPTION(@"Refusing invalid IPv4 #5", OFInvalidFormatException,
	    OFSocketAddressParseIP(@"127.0.a.1", 1234))

	EXPECT_EXCEPTION(@"Refusing invalid IPv4 #6", OFInvalidFormatException,
	    OFSocketAddressParseIP(@"127.0..1", 1234))

	TEST(@"Port of an IPv4 address", OFSocketAddressPort(&addr) == 1234)

	TEST(@"Converting an IPv4 to a string",
	    [OFSocketAddressString(&addr) isEqual: @"127.0.0.1"])

	TEST(@"Parsing an IPv6 #1",
	    R(addr = OFSocketAddressParseIP(
	    @"1122:3344:5566:7788:99aa:bbCc:ddee:ff00", 1234)) &&







|







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

	EXPECT_EXCEPTION(@"Refusing invalid IPv4 #5", OFInvalidFormatException,
	    OFSocketAddressParseIP(@"127.0.a.1", 1234))

	EXPECT_EXCEPTION(@"Refusing invalid IPv4 #6", OFInvalidFormatException,
	    OFSocketAddressParseIP(@"127.0..1", 1234))

	TEST(@"Port of an IPv4 address", OFSocketAddressIPPort(&addr) == 1234)

	TEST(@"Converting an IPv4 to a string",
	    [OFSocketAddressString(&addr) isEqual: @"127.0.0.1"])

	TEST(@"Parsing an IPv6 #1",
	    R(addr = OFSocketAddressParseIP(
	    @"1122:3344:5566:7788:99aa:bbCc:ddee:ff00", 1234)) &&
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

	EXPECT_EXCEPTION(@"Refusing invalid IPv6 #9", OFInvalidFormatException,
	    OFSocketAddressParseIP(@"1:2:3:4:5:6:7::", 1234))

	EXPECT_EXCEPTION(@"Refusing invalid IPv6 #10", OFInvalidFormatException,
	    OFSocketAddressParseIP(@"1:2", 1234))

	TEST(@"Port of an IPv6 address", OFSocketAddressPort(&addr) == 1234)

	SET_V6(addr, 0, 0, 0, 0, 0, 0, 0, 0)
	TEST(@"Converting an IPv6 to a string #1",
	    [OFSocketAddressString(&addr) isEqual: @"::"])

	SET_V6(addr, 0, 0, 0, 0, 0, 0, 0, 1)
	TEST(@"Converting an IPv6 to a string #2",







|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

	EXPECT_EXCEPTION(@"Refusing invalid IPv6 #9", OFInvalidFormatException,
	    OFSocketAddressParseIP(@"1:2:3:4:5:6:7::", 1234))

	EXPECT_EXCEPTION(@"Refusing invalid IPv6 #10", OFInvalidFormatException,
	    OFSocketAddressParseIP(@"1:2", 1234))

	TEST(@"Port of an IPv6 address", OFSocketAddressIPPort(&addr) == 1234)

	SET_V6(addr, 0, 0, 0, 0, 0, 0, 0, 0)
	TEST(@"Converting an IPv6 to a string #1",
	    [OFSocketAddressString(&addr) isEqual: @"::"])

	SET_V6(addr, 0, 0, 0, 0, 0, 0, 0, 1)
	TEST(@"Converting an IPv6 to a string #2",

Modified tests/OFUDPSocketTests.m from [b882de1802] to [435a3297c3].

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
	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) &&
	    [OFSocketAddressString(&addr2) isEqual: @"127.0.0.1"] &&
	    OFSocketAddressPort(&addr2) == port1)

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

	/*
	 * TODO: Move those tests elsewhere as soon as the DNS resolving part
	 *	 is no longer in OFUDPSocket.
	 */







|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
	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) &&
	    [OFSocketAddressString(&addr2) isEqual: @"127.0.0.1"] &&
	    OFSocketAddressIPPort(&addr2) == port1)

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

	/*
	 * TODO: Move those tests elsewhere as soon as the DNS resolving part
	 *	 is no longer in OFUDPSocket.
	 */