ObjFW  Check-in [ca53d41c0f]

Overview
Comment:Autodetect family in -[bindService:onNode:].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ca53d41c0f9543bc50b8c109dd610f3f57be16a8e4500c863ee7bcd15ab8a3e0
User & Date: js on 2011-01-22 23:53:13
Other Links: manifest | tags
Context
2011-01-24
20:20
ObjC++ needs those defines for <stdin.h>. check-in: 5ad479153e user: js tags: trunk
2011-01-22
23:53
Autodetect family in -[bindService:onNode:]. check-in: ca53d41c0f user: js tags: trunk
23:35
Don't send two packets in -[OFStream writeLine:]. check-in: d2b0beab38 user: js tags: trunk
Changes

Modified src/OFExceptions.h from [a9ea4a0db3] to [3d68b9c6ab].

1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
/**
 * \brief An exception indicating that binding a socket failed.
 */
@interface OFBindFailedException: OFException
{
	OFString *node;
	OFString *service;
	int	 family;
	int	 errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, nonatomic) OFString *node;
@property (readonly, nonatomic) OFString *service;
@property (readonly) int family;
@property (readonly) int errNo;
#endif

/**
 * \param class_ The class of the object which caused the exception
 * \param node The node on which binding failed
 * \param service The service on which binding failed
 * \param family The family for which binnding failed
 * \return A new bind failed exception
 */
+ newWithClass: (Class)class_
	  node: (OFString*)node
       service: (OFString*)service
	family: (int)family;

/**
 * Initializes an already allocated bind failed exception.
 *
 * \param class_ The class of the object which caused the exception
 * \param node The node on which binding failed
 * \param service The service on which binding failed
 * \param family The family for which binnding failed
 * \return An initialized bind failed exception
 */
- initWithClass: (Class)class_
	   node: (OFString*)node
	service: (OFString*)service
	 family: (int)family;

/**
 * \return The errno from when the exception was created
 */
- (int)errNo;

/**
 * \return The node on which binding failed
 */
- (OFString*)node;

/**
 * \return The service on which binding failed
 */
- (OFString*)service;

/**
 * \return The family for which binding failed
 */
- (int)family;
@end

/**
 * \brief An exception indicating that listening on the socket failed.
 */
@interface OFListenFailedException: OFException
{







<






<







<




|
<







<




|
<















<
<
<
<
<







1040
1041
1042
1043
1044
1045
1046

1047
1048
1049
1050
1051
1052

1053
1054
1055
1056
1057
1058
1059

1060
1061
1062
1063
1064

1065
1066
1067
1068
1069
1070
1071

1072
1073
1074
1075
1076

1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091





1092
1093
1094
1095
1096
1097
1098
/**
 * \brief An exception indicating that binding a socket failed.
 */
@interface OFBindFailedException: OFException
{
	OFString *node;
	OFString *service;

	int	 errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, nonatomic) OFString *node;
@property (readonly, nonatomic) OFString *service;

@property (readonly) int errNo;
#endif

/**
 * \param class_ The class of the object which caused the exception
 * \param node The node on which binding failed
 * \param service The service on which binding failed

 * \return A new bind failed exception
 */
+ newWithClass: (Class)class_
	  node: (OFString*)node
       service: (OFString*)service;


/**
 * Initializes an already allocated bind failed exception.
 *
 * \param class_ The class of the object which caused the exception
 * \param node The node on which binding failed
 * \param service The service on which binding failed

 * \return An initialized bind failed exception
 */
- initWithClass: (Class)class_
	   node: (OFString*)node
	service: (OFString*)service;


/**
 * \return The errno from when the exception was created
 */
- (int)errNo;

/**
 * \return The node on which binding failed
 */
- (OFString*)node;

/**
 * \return The service on which binding failed
 */
- (OFString*)service;





@end

/**
 * \brief An exception indicating that listening on the socket failed.
 */
@interface OFListenFailedException: OFException
{

Modified src/OFExceptions.m from [8d877139a9] to [ff08f95514].

1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
}
@end

@implementation OFBindFailedException
+ newWithClass: (Class)class_
	  node: (OFString*)node
       service: (OFString*)service
	family: (int)family
{
	return [[self alloc] initWithClass: class_
				      node: node
				   service: service
				    family: family];
}

- initWithClass: (Class)class_
{
	Class c = isa;
	[self release];
	@throw [OFNotImplementedException newWithClass: c
					      selector: _cmd];
}

- initWithClass: (Class)class_
	   node: (OFString*)node_
	service: (OFString*)service_
	 family: (int)family_
{
	self = [super initWithClass: class_];

	@try {
		node	= [node_ copy];
		service	= [service_ copy];
		family	= family_;
		errNo	= GET_SOCK_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;







<



|
<













<






<







1517
1518
1519
1520
1521
1522
1523

1524
1525
1526
1527

1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540

1541
1542
1543
1544
1545
1546

1547
1548
1549
1550
1551
1552
1553
}
@end

@implementation OFBindFailedException
+ newWithClass: (Class)class_
	  node: (OFString*)node
       service: (OFString*)service

{
	return [[self alloc] initWithClass: class_
				      node: node
				   service: service];

}

- initWithClass: (Class)class_
{
	Class c = isa;
	[self release];
	@throw [OFNotImplementedException newWithClass: c
					      selector: _cmd];
}

- initWithClass: (Class)class_
	   node: (OFString*)node_
	service: (OFString*)service_

{
	self = [super initWithClass: class_];

	@try {
		node	= [node_ copy];
		service	= [service_ copy];

		errNo	= GET_SOCK_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606

- (OFString*)description
{
	if (description != nil)
		return description;

	description = [[OFString alloc] initWithFormat:
	    @"Binding service %s on node %s using family %d failed in class "
	    @"%s! " ERRFMT, [service cString], [node cString], family,
	    class_getName(inClass), ERRPARAM];

	return description;
}

- (int)errNo
{
	return errNo;
}

- (OFString*)node
{
	return node;
}

- (OFString*)service
{
	return service;
}

- (int)family
{
	return family;
}
@end

@implementation OFListenFailedException
+ newWithClass: (Class)class_
       backLog: (int)backlog
{
	return [[self alloc] initWithClass: class_







|
|
|


















<
<
<
<
<







1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590





1591
1592
1593
1594
1595
1596
1597

- (OFString*)description
{
	if (description != nil)
		return description;

	description = [[OFString alloc] initWithFormat:
	    @"Binding service %s on node %s failed in class %s! " ERRFMT,
	    [service cString], [node cString], class_getName(inClass),
	    ERRPARAM];

	return description;
}

- (int)errNo
{
	return errNo;
}

- (OFString*)node
{
	return node;
}

- (OFString*)service
{
	return service;
}





@end

@implementation OFListenFailedException
+ newWithClass: (Class)class_
       backLog: (int)backlog
{
	return [[self alloc] initWithClass: class_

Modified src/OFTCPSocket.h from [5f5aec5406] to [4276a55e09].

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
 *
 * \param service The service to bind
 * \param node The node to bind to. Use @"0.0.0.0" for IPv4 or @"::" for IPv6
 *	       to bind to all.
 * \param family The family to use (AF_INET for IPv4 or AF_INET6 for IPv6)
 */
- (void)bindService: (OFString*)service
	     onNode: (OFString*)node
	 withFamily: (int)family;

/**
 * Listen on the socket.
 *
 * \param backlog Maximum length for the queue of pending connections.
 */
- (void)listenWithBackLog: (int)backlog;







|
<







54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
 *
 * \param service The service to bind
 * \param node The node to bind to. Use @"0.0.0.0" for IPv4 or @"::" for IPv6
 *	       to bind to all.
 * \param family The family to use (AF_INET for IPv4 or AF_INET6 for IPv6)
 */
- (void)bindService: (OFString*)service
	     onNode: (OFString*)node;


/**
 * Listen on the socket.
 *
 * \param backlog Maximum length for the queue of pending connections.
 */
- (void)listenWithBackLog: (int)backlog;

Modified src/OFTCPSocket.m from [94deb56f45] to [8771225ab8].

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
		@throw [OFConnectionFailedException newWithClass: isa
							    node: node
							 service: service];
}

- (void)bindService: (OFString*)service
	     onNode: (OFString*)node
	 withFamily: (int)family
{
	if (sock != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException newWithClass: isa];

#ifndef HAVE_THREADSAFE_GETADDRINFO
	if (family != AF_INET)
		@throw [OFBindFailedException newWithClass: isa
						      node: node
						   service: service
						    family: family];
#endif

	if ((sock = socket(family, SOCK_STREAM, 0)) == INVALID_SOCKET)
		@throw [OFBindFailedException newWithClass: isa
						      node: node
						   service: service
						    family: family];

#ifdef HAVE_THREADSAFE_GETADDRINFO
	struct addrinfo hints, *res;

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = family;
	hints.ai_socktype = SOCK_STREAM;

	if (getaddrinfo([node cString], [service cString], &hints, &res)) {
		close(sock);
		sock = INVALID_SOCKET;
		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}





	if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) {
		freeaddrinfo(res);
		close(sock);
		sock = INVALID_SOCKET;
		@throw [OFBindFailedException newWithClass: isa
						      node: node
						   service: service
						    family: family];
	}

	freeaddrinfo(res);
#else
	struct hostent *he;
	struct servent *se;
	struct sockaddr_in addr;







<




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




|


|
<
<




|
>
>
>
>







|
<







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
		@throw [OFConnectionFailedException newWithClass: isa
							    node: node
							 service: service];
}

- (void)bindService: (OFString*)service
	     onNode: (OFString*)node

{
	if (sock != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException newWithClass: isa];















#ifdef HAVE_THREADSAFE_GETADDRINFO
	struct addrinfo hints, *res;

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	if (getaddrinfo([node cString], [service cString], &hints, &res))


		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];

	if ((sock = socket(res->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
		@throw [OFBindFailedException newWithClass: isa
						      node: node
						   service: service];

	if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) {
		freeaddrinfo(res);
		close(sock);
		sock = INVALID_SOCKET;
		@throw [OFBindFailedException newWithClass: isa
						      node: node
						   service: service];

	}

	freeaddrinfo(res);
#else
	struct hostent *he;
	struct servent *se;
	struct sockaddr_in addr;
270
271
272
273
274
275
276
277
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
309
310
311
312
313
314
315
316
317
318
319
320
	if ((se = getservbyname([service cString], "TCP")) != NULL)
		port = se->s_port;
	else if ((port = OF_BSWAP16_IF_LE(strtol([service cString], NULL,
	    10))) == 0) {
# ifdef OF_THREADS
		[mutex unlock];
# endif
		close(sock);
		sock = INVALID_SOCKET;
		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = port;

	if (he->h_addrtype != AF_INET || he->h_addr_list[0] == NULL) {
# ifdef OF_THREADS
		[mutex unlock];
# endif
		close(sock);
		sock = INVALID_SOCKET;
		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	memcpy(&addr.sin_addr.s_addr, he->h_addr_list[0], he->h_length);

# ifdef OF_THREADS
	[mutex unlock];
# endif





	if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
		close(sock);
		sock = INVALID_SOCKET;
		@throw [OFBindFailedException newWithClass: isa
						      node: node
						   service: service
						    family: family];
	}
#endif
}

- (void)listenWithBackLog: (int)backlog
{
	if (sock == INVALID_SOCKET)







<
<














<
<











>
>
>
>






|
<







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
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
	if ((se = getservbyname([service cString], "TCP")) != NULL)
		port = se->s_port;
	else if ((port = OF_BSWAP16_IF_LE(strtol([service cString], NULL,
	    10))) == 0) {
# ifdef OF_THREADS
		[mutex unlock];
# endif


		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = port;

	if (he->h_addrtype != AF_INET || he->h_addr_list[0] == NULL) {
# ifdef OF_THREADS
		[mutex unlock];
# endif


		@throw [OFAddressTranslationFailedException
		    newWithClass: isa
			    node: node
			 service: service];
	}

	memcpy(&addr.sin_addr.s_addr, he->h_addr_list[0], he->h_length);

# ifdef OF_THREADS
	[mutex unlock];
# endif
	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
		@throw [OFBindFailedException newWithClass: isa
						      node: node
						   service: service];

	if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
		close(sock);
		sock = INVALID_SOCKET;
		@throw [OFBindFailedException newWithClass: isa
						      node: node
						   service: service];

	}
#endif
}

- (void)listenWithBackLog: (int)backlog
{
	if (sock == INVALID_SOCKET)

Modified tests/OFTCPSocketTests.m from [85d97971df] to [fca04a710e].

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
		port += 1024;
	service = [OFString stringWithFormat: @"%d", port];

	TEST(@"+[socket]", (server = [OFTCPSocket socket]) &&
	    (client = [OFTCPSocket socket]))

	msg = [OFString stringWithFormat:
	    @"-[bindService:onNode:withFamily:] (port %d)", port];
	TEST(msg, R([server bindService: service
				 onNode: @"127.0.0.1"
			     withFamily: AF_INET]))

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

	TEST(@"-[connectToService:onNode:]",
	    R([client connectToService: service
				onNode: @"127.0.0.1"]))








|

|
<







45
46
47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
		port += 1024;
	service = [OFString stringWithFormat: @"%d", port];

	TEST(@"+[socket]", (server = [OFTCPSocket socket]) &&
	    (client = [OFTCPSocket socket]))

	msg = [OFString stringWithFormat:
	    @"-[bindService:onNode:] (port %d)", port];
	TEST(msg, R([server bindService: service
				 onNode: @"127.0.0.1"]))


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

	TEST(@"-[connectToService:onNode:]",
	    R([client connectToService: service
				onNode: @"127.0.0.1"]))