ObjFW  Check-in [8866fca78d]

Overview
Comment:OFDDPSocket: Revert not including node in bind

Looking at the NetBSD code (/usr/src/sys/netatalk/ddp_usrreq.c), it
seems to be allowed to specify a node after all, contrary to what
atalk(4) says. Looking at the Linux code (net/appletalk/ddp.c) seems to
confirm this.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 8866fca78d8dcf9056ca54333a4ceb89e76f8b7594d06583ed411646238e60dd
User & Date: js on 2022-10-26 22:17:16
Other Links: manifest | tags
Context
2022-10-30
18:25
OFSystemInfo: Add fallback to MAX_PATH check-in: a3caef326b user: js tags: trunk
2022-10-26
22:17
OFDDPSocket: Revert not including node in bind check-in: 8866fca78d user: js tags: trunk
20:58
configure: Prefer GnuTLS over OpenSSL check-in: b8d47bbbf0 user: js tags: trunk
2022-10-25
21:30
OFDDPSocket: Don't include node in bind check-in: 607d4d083c user: js tags: trunk
Changes

Modified src/OFDDPSocket.h from [6bae3c2189] to [987ad37c95].

58
59
60
61
62
63
64
65

66
67

68
69
70
71
72
73
74



75
76
77
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80







-
+


+






-
+
+
+



 * @note The delegate is retained for as long as asynchronous operations are
 *	 still ongoing.
 */
@property OF_NULLABLE_PROPERTY (assign, nonatomic)
    id <OFDDPSocketDelegate> delegate;

/**
 * @brief Bind the socket to the specified network and port.
 * @brief Bind the socket to the specified network, node and port.
 *
 * @param network The network to bind to. 0 means any.
 * @param node The node to bind to. 0 means "this node".
 * @param port The port to bind to. 0 means to pick one and return it via the
 *	       returned socket address.
 * @return The address on which this socket can be reached
 * @throw OFBindDDPSockeFailedException Binding failed
 * @throw OFAlreadyConnectedException The socket is already bound
 */
- (OFSocketAddress)bindToNetwork: (uint16_t)network port: (uint8_t)port;
- (OFSocketAddress)bindToNetwork: (uint16_t)network
			    node: (uint8_t)node
			    port: (uint8_t)port;
@end

OF_ASSUME_NONNULL_END

Modified src/OFDDPSocket.m from [c23e962b99] to [b54a9f63cf].

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







-
+
+
+









-
+





+




















+


















+











+









#import "OFAlreadyConnectedException.h"
#import "OFBindDDPSocketFailedException.h"

@implementation OFDDPSocket
@dynamic delegate;

- (OFSocketAddress)bindToNetwork: (uint16_t)network port: (uint8_t)port
- (OFSocketAddress)bindToNetwork: (uint16_t)network
			    node: (uint8_t)node
			    port: (uint8_t)port
{
	OFSocketAddress address;
#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC)
	int flags;
#endif

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

	address = OFSocketAddressMakeAppleTalk(network, 0, port);
	address = OFSocketAddressMakeAppleTalk(network, node, port);

	if ((_socket = socket(address.sockaddr.at.sat_family,
	    SOCK_DGRAM | SOCK_CLOEXEC, 0)) == OFInvalidSocketHandle)
		@throw [OFBindDDPSocketFailedException
		    exceptionWithNetwork: network
				    node: node
				    port: port
				  socket: self
				   errNo: OFSocketErrNo()];

	_canBlock = true;

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

	if (bind(_socket, (struct sockaddr *)&address.sockaddr,
	    address.length) != 0) {
		int errNo = OFSocketErrNo();

		closesocket(_socket);
		_socket = OFInvalidSocketHandle;

		@throw [OFBindDDPSocketFailedException
		    exceptionWithNetwork: network
				    node: node
				    port: port
				  socket: self
				   errNo: errNo];
	}

	memset(&address, 0, sizeof(address));
	address.family = OFSocketAddressFamilyAppleTalk;
	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 [OFBindDDPSocketFailedException
		    exceptionWithNetwork: network
				    node: node
				    port: port
				  socket: self
				   errNo: errNo];
	}

	if (address.sockaddr.at.sat_family != AF_APPLETALK) {
		closesocket(_socket);
		_socket = OFInvalidSocketHandle;

		@throw [OFBindDDPSocketFailedException
		    exceptionWithNetwork: network
				    node: node
				    port: port
				  socket: self
				   errNo: EAFNOSUPPORT];
	}

	return address;
}
@end

Modified src/exceptions/OFBindDDPSocketFailedException.h from [7a444cec92] to [218affa1e0].

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







-
+







+
+
+
+
+









+






+











+






+








 *
 * @brief An exception indicating that binding a DDP socket failed.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFBindDDPSocketFailedException: OFBindSocketFailedException
{
	uint16_t _network;
	uint8_t _port;
	uint8_t _node, _port;
}

/**
 * @brief The DDP network on which binding failed.
 */
@property (readonly, nonatomic) uint16_t network;

/**
 * @brief The DDP node for which binding failed.
 */
@property (readonly, nonatomic) uint8_t node;

/**
 * @brief The DDP port on which binding failed.
 */
@property (readonly, nonatomic) uint8_t port;

/**
 * @brief Creates a new, autoreleased bind DDP socket failed exception.
 *
 * @param network The DDP network on which binding failed
 * @param node The DDP node for which binding failed
 * @param port The DDP port on which binding failed
 * @param socket The socket which could not be bound
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased bind DDP socket failed exception
 */
+ (instancetype)exceptionWithNetwork: (uint16_t)network
				node: (uint8_t)node
				port: (uint8_t)port
			      socket: (id)socket
			       errNo: (int)errNo;

+ (instancetype)exceptionWithSocket: (id)socket
			      errNo: (int)errNo OF_UNAVAILABLE;

/**
 * @brief Initializes an already allocated bind DDP socket failed exception.
 *
 * @param network The DDP network on which binding failed
 * @param node The DDP node for which binding failed
 * @param port The DDP port on which binding failed
 * @param socket The socket which could not be bound
 * @param errNo The errno of the error that occurred
 * @return An initialized bind DDP socket failed exception
 */
- (instancetype)initWithNetwork: (uint16_t)network
			   node: (uint8_t)node
			   port: (uint8_t)port
			 socket: (id)socket
			  errNo: (int)errNo OF_DESIGNATED_INITIALIZER;

- (instancetype)initWithSocket: (id)socket errNo: (int)errNo OF_UNAVAILABLE;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFBindDDPSocketFailedException.m from [6c18b1ebdf] to [dbb639a5e2].

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







-
+







+





+











+








+












-
-
-
+
+
+


#include "config.h"

#import "OFBindDDPSocketFailedException.h"
#import "OFData.h"
#import "OFString.h"

@implementation OFBindDDPSocketFailedException
@synthesize network = _network, port = _port;
@synthesize network = _network, node = _node, port = _port;

+ (instancetype)exceptionWithSocket: (id)sock errNo: (int)errNo
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (instancetype)exceptionWithNetwork: (uint16_t)network
				node: (uint8_t)node
				port: (uint8_t)port
			      socket: (id)sock
			       errNo: (int)errNo
{
	return [[[self alloc] initWithNetwork: network
					 node: node
					 port: port
				       socket: sock
					errNo: errNo] autorelease];
}

- (instancetype)initWithSocket: (id)sock errNo: (int)errNo
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithNetwork: (uint16_t)network
			   node: (uint8_t)node
			   port: (uint8_t)port
			 socket: (id)sock
			  errNo: (int)errNo
{
	self = [super initWithSocket: sock errNo: errNo];

	@try {
		_network = network;
		_node = node;
		_port = port;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Binding to port %" @PRIx8 @" on network %" PRIx16 @" failed in "
	    @"socket of type %@: %@",
	    _port, _network, [_socket class], OFStrError(_errNo)];
	    @"Binding to port %" @PRIx8 @" of node %" @PRIx8 @" on network "
	    @"%" PRIx16 @" failed in socket of type %@: %@",
	    _port, _node, _network, [_socket class], OFStrError(_errNo)];
}
@end

Modified tests/OFDDPSocketTests.m from [e653bd7196] to [cbe290bc1c].

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







-
-
+
+





-
+





-
+







	OFDDPSocket *sock;
	OFSocketAddress address1, address2;
	char buffer[5];

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

	@try {
		TEST(@"-[bindToNetwork:port:]",
		    R(address1 = [sock bindToNetwork: 0 port: 0]))
		TEST(@"-[bindToNetwork:node:port:]",
		    R(address1 = [sock bindToNetwork: 0 node: 0 port: 0]))
	} @catch (OFBindSocketFailedException *e) {
		switch (e.errNo) {
		case EAFNOSUPPORT:
			[OFStdOut setForegroundColor: [OFColor lime]];
			[OFStdOut writeLine:
			    @"\r[OFDDPSocket] -[bindToNetwork:port:] "
			    @"\r[OFDDPSocket] -[bindToNetwork:node:port:] "
			    @"AppleTalk unsupported, skipping tests"];
			break;
		case EADDRNOTAVAIL:
			[OFStdOut setForegroundColor: [OFColor lime]];
			[OFStdOut writeLine:
			    @"\r[OFDDPSocket] -[bindToNetwork:port:] "
			    @"\r[OFDDPSocket] -[bindToNetwork:node:port:] "
			    @"AppleTalk not configured, skipping tests"];
			break;
		default:
			@throw e;
		}

		objc_autoreleasePoolPop(pool);