ObjFW  Diff

Differences From Artifact [1565c3535f]:

To Artifact [0ec27b8819]:


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







-
-
+
+






+




+

-
-
+
+
-
-
+
-



















-
-
-

-








-
+




-
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


-
+







-
-
-
+
+
+
-








	sock = INVALID_SOCKET;
	sockAddr = NULL;

	return self;
}

- (void)connectToService: (OFString*)service
		  onNode: (OFString*)node
- (void)connectToHost: (OFString*)host
	       onPort: (uint16_t)port
{
	if (sock != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException newWithClass: isa];

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

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	snprintf(port_s, 7, "%" PRIu16, port);

	if (getaddrinfo([node cString], [service cString], &hints, &res0))
		@throw [OFAddressTranslationFailedException
	if (getaddrinfo([host cString], port_s, &hints, &res0))
		@throw [OFAddressTranslationFailedException newWithClass: isa
		    newWithClass: isa
			    node: node
								    host: host];
			 service: service];

	for (res = res0; res != NULL; res = res->ai_next) {
		if ((sock = socket(res->ai_family, res->ai_socktype,
		    res->ai_protocol)) == INVALID_SOCKET)
			continue;

		if (connect(sock, res->ai_addr, res->ai_addrlen) == -1) {
			close(sock);
			sock = INVALID_SOCKET;
			continue;
		}

		break;
	}

	freeaddrinfo(res0);
#else
	BOOL connected = NO;
	struct hostent *he;
# ifndef _PSP
	struct servent *se;
# endif
	struct sockaddr_in addr;
	uint16_t port;
	char **ip;
# ifdef OF_THREADS
	OFDataArray *addrlist;

	addrlist = [[OFDataArray alloc] initWithItemSize: sizeof(char**)];
	[mutex lock];
# endif

	if ((he = gethostbyname([node cString])) == NULL) {
	if ((he = gethostbyname([host cString])) == NULL) {
# ifdef OF_THREADS
		[addrlist release];
		[mutex unlock];
# endif
		@throw [OFAddressTranslationFailedException
		@throw [OFAddressTranslationFailedException newWithClass: isa
		    newWithClass: isa
			    node: node
			 service: service];
	}

								    host: host];
# ifndef _PSP
	if ((se = getservbyname([service cString], "tcp")) != NULL)
		port = se->s_port;
	else {
# endif
		@try {
			intmax_t p = [service decimalValue];

	}
			if (p < 1 || p > 65535)
				@throw [OFOutOfRangeException
				    newWithClass: isa];

			port = of_bswap16_if_le(p);
		} @catch (OFInvalidFormatException *e) {
			[e release];
# ifdef OF_THREADS
			[addrlist release];
			[mutex unlock];
# endif
			@throw [OFAddressTranslationFailedException
			    newWithClass: isa
				    node: node
				 service: service];
		} @catch (id e) {
# ifdef OF_THREADS
			[addrlist release];
			[mutex unlock];
# endif
			@throw e;
		}
# ifndef _PSP
	}
# endif

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

	if (he->h_addrtype != AF_INET ||
	    (sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
# ifdef OF_THREADS
		[addrlist release];
		[mutex unlock];
# endif
		@throw [OFConnectionFailedException
		    newWithClass: isa
			    node: node
		@throw [OFConnectionFailedException newWithClass: isa
							    host: host
							    port: port];
			 service: service];
	}

# ifdef OF_THREADS
	@try {
		for (ip = he->h_addr_list; *ip != NULL; ip++)
			[addrlist addItem: ip];

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

322
323

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







-
-
+
+


-
-
+
+






+




+

-
-
+
+
-
-
+
-



-
-
+
+






-
-
+
+





-
-
-

-





-
+



-
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


-
+





-
+
-
-
+
-









-
-
+
+





-
-
+
+







		close(sock);
		sock = INVALID_SOCKET;
	}
#endif

	if (sock == INVALID_SOCKET)
		@throw [OFConnectionFailedException newWithClass: isa
							    node: node
							 service: service];
							    host: host
							    port: port];
}

- (void)bindService: (OFString*)service
	     onNode: (OFString*)node
- (void)bindToPort: (uint16_t)port
	    onHost: (OFString*)host
{
	if (sock != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException newWithClass: isa];

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

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	snprintf(port_s, 7, "%" PRIu16, port);

	if (getaddrinfo([node cString], [service cString], &hints, &res))
		@throw [OFAddressTranslationFailedException
	if (getaddrinfo([host cString], port_s, &hints, &res))
		@throw [OFAddressTranslationFailedException newWithClass: isa
		    newWithClass: isa
			    node: node
								    host: host];
			 service: service];

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

	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];
						      host: host
						      port: port];
	}

	freeaddrinfo(res);
#else
	struct hostent *he;
# ifndef _PSP
	struct servent *se;
# endif
	struct sockaddr_in addr;
	uint16_t port;

# ifdef OF_THREADS
	[mutex lock];
# endif

	if ((he = gethostbyname([node cString])) == NULL) {
	if ((he = gethostbyname([host cString])) == NULL) {
# ifdef OF_THREADS
		[mutex unlock];
# endif
		@throw [OFAddressTranslationFailedException
		@throw [OFAddressTranslationFailedException newWithClass: isa
		    newWithClass: isa
			    node: node
			 service: service];
	}

								    host: host];
# ifndef _PSP
	if ((se = getservbyname([service cString], "tcp")) != NULL)
		port = se->s_port;
	else {
# endif
		@try {
			intmax_t p = [service decimalValue];

	}
			if (p < 1 || p > 65535)
				@throw [OFOutOfRangeException
				    newWithClass: isa];

			port = of_bswap16_if_le(p);
		} @catch (OFInvalidFormatException *e) {
			[e release];
# ifdef OF_THREADS
			[mutex unlock];
# endif
			@throw [OFAddressTranslationFailedException
			    newWithClass: isa
				    node: node
				 service: service];
		} @catch (id e) {
# ifdef OF_THREADS
			[mutex unlock];
# endif
			@throw e;
		}
# ifndef _PSP
	}
# endif

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

	if (he->h_addrtype != AF_INET || he->h_addr_list[0] == NULL) {
# ifdef OF_THREADS
		[mutex unlock];
# endif
		@throw [OFAddressTranslationFailedException
		@throw [OFAddressTranslationFailedException newWithClass: isa
		    newWithClass: isa
			    node: node
								    host: host];
			 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];
						      host: host
						      port: port];

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

- (void)listenWithBackLog: (int)backlog
{
	if (sock == INVALID_SOCKET)
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
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







-
+


-
+




-
+

-
+


-
+






-
+

-
+



-
+







- (OFString*)remoteAddress
{
	if (sockAddr == NULL || sockAddrLen == 0)
		@throw [OFInvalidArgumentException newWithClass: isa
						       selector: _cmd];

#ifdef HAVE_THREADSAFE_GETADDRINFO
	char *node = [self allocMemoryWithSize: NI_MAXHOST];
	char *host = [self allocMemoryWithSize: NI_MAXHOST];

	@try {
		if (getnameinfo(sockAddr, sockAddrLen, node, NI_MAXHOST, NULL,
		if (getnameinfo(sockAddr, sockAddrLen, host, NI_MAXHOST, NULL,
		    0, NI_NUMERICHOST))
			@throw [OFAddressTranslationFailedException
			    newWithClass: isa];

		return [OFString stringWithCString: node];
		return [OFString stringWithCString: host];
	} @finally {
		[self freeMemory: node];
		[self freeMemory: host];
	}
#else
	char *node;
	char *host;

# ifdef OF_THREADS
	[mutex lock];

	@try {
# endif
		node = inet_ntoa(((struct sockaddr_in*)sockAddr)->sin_addr);
		host = inet_ntoa(((struct sockaddr_in*)sockAddr)->sin_addr);

		if (node == NULL)
		if (host == NULL)
			@throw [OFAddressTranslationFailedException
			    newWithClass: isa];

		return [OFString stringWithCString: node];
		return [OFString stringWithCString: host];
# ifdef OF_THREADS
	} @finally {
		[mutex unlock];
	}
# endif
#endif