ObjFW  Check-in [ca113e0145]

Overview
Comment:Don't bind to port 0 on the Wii.

Instead, a decreasing variable is used now. This should be safe, as
nothing else should be binding ports while homebrew code is running. The
only problem that could arise is when code manually binds to very high
port numbers.

This also solves the problem that getsockname() is not available on the
Wii, as we know the port now anyway.

And while we're at it, this also adds struct sockaddr_storage.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ca113e0145659828611d77eb7f588400352b86dadcf46f0f4c9a5b5607b74c56
User & Date: js on 2013-06-13 02:03:13
Other Links: manifest | tags
Context
2013-06-14
22:59
Clean up OFXMLParser a little. check-in: 568ec65e80 user: js tags: trunk
2013-06-13
02:03
Don't bind to port 0 on the Wii. check-in: ca113e0145 user: js tags: trunk
01:59
Try inet_addr() before gethostbyname(). check-in: 8faa16f249 user: js tags: trunk
Changes

Modified src/OFStreamObserver.m from [ec4b8afafc] to [2bcf8ed1eb].

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#import "macros.h"

#ifdef __wii__
# define BOOL OGC_BOOL
# include <network.h>
# undef BOOL
# define bind(sock, addr, addrlen) net_bind(sock, addr, addrlen)
# define getsockname(sock, addr, addrlen) net_getsockname(sock, addr, addrlen)
# define sendto(sock, buf, len, flags, addr, addrlen) \
	net_sendto(sock, buf, len, flags, addr, addrlen)
# define socket(domain, type, proto) net_socket(domain, type, proto)
#endif

enum {
	QUEUE_ADD = 0,







<







58
59
60
61
62
63
64

65
66
67
68
69
70
71
#import "macros.h"

#ifdef __wii__
# define BOOL OGC_BOOL
# include <network.h>
# undef BOOL
# define bind(sock, addr, addrlen) net_bind(sock, addr, addrlen)

# define sendto(sock, buf, len, flags, addr, addrlen) \
	net_sendto(sock, buf, len, flags, addr, addrlen)
# define socket(domain, type, proto) net_socket(domain, type, proto)
#endif

enum {
	QUEUE_ADD = 0,
111
112
113
114
115
116
117

118

119
120
121
122
123
124
125
- init
{
	self = [super init];

	@try {
#ifndef OF_HAVE_PIPE
		struct sockaddr_in cancelAddr2;

		socklen_t cancelAddrLen;

#endif

		_readStreams = [[OFMutableArray alloc] init];
		_writeStreams = [[OFMutableArray alloc] init];
		_queue = [[OFMutableArray alloc] init];
		_queueInfo = [[OFDataArray alloc]
		    initWithItemSize: sizeof(int)];







>

>







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
- init
{
	self = [super init];

	@try {
#ifndef OF_HAVE_PIPE
		struct sockaddr_in cancelAddr2;
# ifndef __wii__
		socklen_t cancelAddrLen;
# endif
#endif

		_readStreams = [[OFMutableArray alloc] init];
		_writeStreams = [[OFMutableArray alloc] init];
		_queue = [[OFMutableArray alloc] init];
		_queueInfo = [[OFDataArray alloc]
		    initWithItemSize: sizeof(int)];
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
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		_cancelAddr.sin_family = AF_INET;
		_cancelAddr.sin_port = 0;
		_cancelAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
		cancelAddr2 = _cancelAddr;







		if (bind(_cancelFD[0], (struct sockaddr*)&_cancelAddr,
		    sizeof(_cancelAddr)) || bind(_cancelFD[1],
		    (struct sockaddr*)&cancelAddr2, sizeof(cancelAddr2)))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];


		cancelAddrLen = sizeof(_cancelAddr);
		if (getsockname(_cancelFD[0], (struct sockaddr*)&_cancelAddr,
		    &cancelAddrLen))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

#endif

		_maxFD = _cancelFD[0];
		_FDToStream = [self allocMemoryWithSize: sizeof(OFStream*)
						  count: _maxFD + 1];
		_FDToStream[_cancelFD[0]] = nil;








>
>
>
>
>
>







>





>







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
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		_cancelAddr.sin_family = AF_INET;
		_cancelAddr.sin_port = 0;
		_cancelAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
		cancelAddr2 = _cancelAddr;

# ifdef __wii__
		/* The Wii does not accept port 0 as "choose any free port" */
		_cancelAddr.sin_port = 65533;
		cancelAddr2.sin_port = 65534;
# endif

		if (bind(_cancelFD[0], (struct sockaddr*)&_cancelAddr,
		    sizeof(_cancelAddr)) || bind(_cancelFD[1],
		    (struct sockaddr*)&cancelAddr2, sizeof(cancelAddr2)))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

# ifndef __wii__
		cancelAddrLen = sizeof(_cancelAddr);
		if (getsockname(_cancelFD[0], (struct sockaddr*)&_cancelAddr,
		    &cancelAddrLen))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];
# endif
#endif

		_maxFD = _cancelFD[0];
		_FDToStream = [self allocMemoryWithSize: sizeof(OFStream*)
						  count: _maxFD + 1];
		_FDToStream[_cancelFD[0]] = nil;

Modified src/OFTCPSocket.m from [73d0c39dd0] to [17c2cc5542].

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

#ifdef __wii__
# define accept(sock, addr, addrlen) net_accept(sock, addr, addrlen)
# define bind(sock, addr, addrlen) net_bind(sock, addr, addrlen)
# define close(sock) net_close(sock)
# define connect(sock, addr, addrlen) net_connect(sock, addr, addrlen)
# define gethostbyname(name) net_gethostbyname(name)
# define getsockname(sock, addr, addrlen) net_getsockname(sock, addr, addrlen)
# define listen(sock, backlog) net_listen(sock, backlog)
# define setsockopt(sock, level, name, value, len) \
	net_setsockopt(sock, level, name, value, len)
# define socket(domain, type, proto) net_socket(domain, type, proto)
typedef u32 in_addr_t;






#endif

/* References for static linking */
void _references_to_categories_of_OFTCPSocket(void)
{
	_OFTCPSocket_SOCKS5_reference = 1;
}

Class of_tls_socket_class = Nil;

static OFString *defaultSOCKS5Host = nil;
static uint16_t defaultSOCKS5Port = 1080;





#ifdef OF_HAVE_THREADS
@interface OFTCPSocket_ConnectThread: OFThread
{
	OFThread *_sourceThread;
	OFTCPSocket *_socket;
	OFString *_host;







<





>
>
>
>
>
>












>
>
>
>







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

#ifdef __wii__
# define accept(sock, addr, addrlen) net_accept(sock, addr, addrlen)
# define bind(sock, addr, addrlen) net_bind(sock, addr, addrlen)
# define close(sock) net_close(sock)
# define connect(sock, addr, addrlen) net_connect(sock, addr, addrlen)
# define gethostbyname(name) net_gethostbyname(name)

# define listen(sock, backlog) net_listen(sock, backlog)
# define setsockopt(sock, level, name, value, len) \
	net_setsockopt(sock, level, name, value, len)
# define socket(domain, type, proto) net_socket(domain, type, proto)
typedef u32 in_addr_t;

struct sockaddr_storage {
	u8 ss_len;
	u8 ss_family;
	u8 ss_data[14];
};
#endif

/* References for static linking */
void _references_to_categories_of_OFTCPSocket(void)
{
	_OFTCPSocket_SOCKS5_reference = 1;
}

Class of_tls_socket_class = Nil;

static OFString *defaultSOCKS5Host = nil;
static uint16_t defaultSOCKS5Port = 1080;

#ifdef __wii__
static uint16_t freePort = 65532;
#endif

#ifdef OF_HAVE_THREADS
@interface OFTCPSocket_ConnectThread: OFThread
{
	OFThread *_sourceThread;
	OFTCPSocket *_socket;
	OFString *_host;
536
537
538
539
540
541
542

543

544
545
546
547
548
549
550
551
552
553





554
555
556
557
558
559
560
	union {
		struct sockaddr_storage storage;
		struct sockaddr_in in;
#ifdef AF_INET6
		struct sockaddr_in6 in6;
#endif
	} addr;

	socklen_t addrLen;


	if (_socket != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException
		    exceptionWithClass: [self class]
				socket: self];

	if (_SOCKS5Host != nil)
		@throw [OFNotImplementedException
		    exceptionWithClass: [self class]
			      selector: _cmd];






#ifdef HAVE_THREADSAFE_GETADDRINFO
	struct addrinfo hints, *res;
	char portCString[7];

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







>

>










>
>
>
>
>







545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
	union {
		struct sockaddr_storage storage;
		struct sockaddr_in in;
#ifdef AF_INET6
		struct sockaddr_in6 in6;
#endif
	} addr;
#ifndef __wii__
	socklen_t addrLen;
#endif

	if (_socket != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException
		    exceptionWithClass: [self class]
				socket: self];

	if (_SOCKS5Host != nil)
		@throw [OFNotImplementedException
		    exceptionWithClass: [self class]
			      selector: _cmd];

#ifdef __wii__
	if (port == 0)
		port = freePort--;
#endif

#ifdef HAVE_THREADSAFE_GETADDRINFO
	struct addrinfo hints, *res;
	char portCString[7];

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
651
652
653
654
655
656
657

658
659
660
661
662
663
664
665
666
667
668
669
670
671
672

673
674
675
676
677
678
679
							    port: port];
	}
#endif

	if (port > 0)
		return port;


	addrLen = sizeof(addr.storage);
	if (getsockname(_socket, (struct sockaddr*)&addr, &addrLen)) {
		close(_socket);
		_socket = INVALID_SOCKET;
		@throw [OFBindFailedException exceptionWithClass: [self class]
							  socket: self
							    host: host
							    port: port];
	}

	if (addr.storage.ss_family == AF_INET)
		return OF_BSWAP16_IF_LE(addr.in.sin_port);
#ifdef AF_INET6
	if (addr.storage.ss_family == AF_INET6)
		return OF_BSWAP16_IF_LE(addr.in6.sin6_port);

#endif

	close(_socket);
	_socket = INVALID_SOCKET;
	@throw [OFBindFailedException exceptionWithClass: [self class]
						  socket: self
						    host: host







>












|


>







667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
							    port: port];
	}
#endif

	if (port > 0)
		return port;

#ifndef __wii__
	addrLen = sizeof(addr.storage);
	if (getsockname(_socket, (struct sockaddr*)&addr, &addrLen)) {
		close(_socket);
		_socket = INVALID_SOCKET;
		@throw [OFBindFailedException exceptionWithClass: [self class]
							  socket: self
							    host: host
							    port: port];
	}

	if (addr.storage.ss_family == AF_INET)
		return OF_BSWAP16_IF_LE(addr.in.sin_port);
# ifdef AF_INET6
	if (addr.storage.ss_family == AF_INET6)
		return OF_BSWAP16_IF_LE(addr.in6.sin6_port);
# endif
#endif

	close(_socket);
	_socket = INVALID_SOCKET;
	@throw [OFBindFailedException exceptionWithClass: [self class]
						  socket: self
						    host: host