Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 537616 | Differences between
and this patch

Collapse All | Expand All

(-)a/src/clinet.c (-3 / +149 lines)
Lines 31-36 Link Here
31
31
32
#include <stdio.h>
32
#include <stdio.h>
33
#include <stdlib.h>
33
#include <stdlib.h>
34
#include <stddef.h>
34
#include <unistd.h>
35
#include <unistd.h>
35
#include <string.h>
36
#include <string.h>
36
#include <fcntl.h>
37
#include <fcntl.h>
Lines 42-49 Link Here
42
#include <sys/types.h>
43
#include <sys/types.h>
43
#include <sys/socket.h>
44
#include <sys/socket.h>
44
45
46
#include <arpa/inet.h>
45
#include <netinet/in.h>
47
#include <netinet/in.h>
46
#include <netinet/tcp.h>
48
#include <netinet/tcp.h>
49
#include <sys/un.h>
47
50
48
#include <netdb.h>
51
#include <netdb.h>
49
52
Lines 161-167 out_failed: Link Here
161
/**
164
/**
162
 * Open a socket to a tcp remote host with the specified port.
165
 * Open a socket to a tcp remote host with the specified port.
163
 **/
166
 **/
164
int dcc_connect_by_name(const char *host, int port, int *p_fd)
167
static int dcc_connect_by_name_real(const char *host, int port, int *p_fd)
165
{
168
{
166
    struct addrinfo hints;
169
    struct addrinfo hints;
167
    struct addrinfo *res;
170
    struct addrinfo *res;
Lines 201-207 int dcc_connect_by_name(const char *host, int port, int *p_fd) Link Here
201
 *
204
 *
202
 * @todo Don't try for too long to connect.
205
 * @todo Don't try for too long to connect.
203
 **/
206
 **/
204
int dcc_connect_by_name(const char *host, int port, int *p_fd)
207
static int dcc_connect_by_name_real(const char *host, int port, int *p_fd)
205
{
208
{
206
    struct sockaddr_in sock_out;
209
    struct sockaddr_in sock_out;
207
    struct hostent *hp;
210
    struct hostent *hp;
Lines 224-226 int dcc_connect_by_name(const char *host, int port, int *p_fd) Link Here
224
}
227
}
225
228
226
#endif /* not ENABLE_RFC2553 */
229
#endif /* not ENABLE_RFC2553 */
227
- 
230
231
static int dcc_connect_via_socks5(const char *host, int port, int *p_fd, const char *proxy)
232
{
233
	int ret;
234
	char *proxy_host, *proxy_it;
235
	int proxy_port;
236
	char buf[262];
237
	int host_length;
238
	struct sockaddr_in addr_buf;
239
	int skip_bytes;
240
241
	host_length = strlen(host);
242
	if (host_length > 255) {
243
		rs_log_error("hostname \"%s\" too long for SOCKSv5 (over 255 chars)", host);
244
		return EXIT_CONNECT_FAILED;
245
	}
246
247
	if (proxy[0] == '/') { /* UNIX socket */
248
		struct sockaddr_un unix_addr;
249
250
		if (strlen(proxy) >= sizeof(unix_addr.sun_path))
251
		{
252
			rs_log_error("UNIX socket path \"%s\" too long", proxy);
253
			return EXIT_CONNECT_FAILED;
254
		}
255
256
		unix_addr.sun_family = AF_UNIX;
257
		strcpy(unix_addr.sun_path, proxy);
258
259
		ret = dcc_connect_by_addr((struct sockaddr *) &unix_addr,
260
				offsetof(struct sockaddr_un, sun_path) + strlen(proxy) + 1,
261
				p_fd);
262
263
	} else { /* hostname? IP address? */
264
		proxy_host = strdup(proxy);
265
		if (proxy_host == NULL) return EXIT_OUT_OF_MEMORY;
266
267
		proxy_it = strrchr(proxy_host, ':');
268
		if (proxy_it) {
269
			*(proxy_it++) = 0;
270
			proxy_port = atoi(proxy_it);
271
272
			if (proxy_port <= 0) {
273
				rs_log_error("invalid proxy port \"%s\"", proxy_it);
274
				free(proxy_host);
275
				return EXIT_CONNECT_FAILED;
276
			}
277
		}
278
		else
279
			proxy_port = 1080;
280
281
		ret = dcc_connect_by_name_real(proxy_host, proxy_port, p_fd);
282
		free(proxy_host);
283
	}
284
285
	if (ret != 0)
286
		return ret;
287
288
	/* connected to proxy, now identifier/method selection */
289
	buf[0] = 0x05; /* SOCKSv5 */
290
	buf[1] = 0x01; /* one method */
291
	buf[2] = 0x00; /* NO AUTHENTICATION REQUIRED */
292
	ret = dcc_writex(*p_fd, buf, 3);
293
	if (ret != 0) {
294
		close(*p_fd);
295
		return ret;
296
	}
297
298
	/* wait for method selection */
299
	ret = dcc_readx(*p_fd, buf, 2);
300
	if (ret != 0) {
301
		close(*p_fd);
302
		return ret;
303
	}
304
	if (buf[0] != 0x05 || buf[1] != 0x00) { /* version, method */
305
		rs_log_error("invalid proxy reply (version 0x%02x, method 0x%02x)",
306
				buf[0], buf[1]);
307
		close(*p_fd);
308
		return EXIT_CONNECT_FAILED;
309
	}
310
311
	/* send connect request */
312
	buf[0] = 0x05; /* SOCKSv5 */
313
	buf[1] = 0x01; /* CONNECT command */
314
	buf[2] = 0x00; /* reserved */
315
	buf[3] = 0x03; /* DOMAINNAME address type */
316
	buf[4] = host_length;
317
	memcpy(&buf[5], host, host_length);
318
	addr_buf.sin_port = htons(port);
319
	memcpy(&buf[5 + host_length], &addr_buf.sin_port, 2);
320
	ret = dcc_writex(*p_fd, buf, 7 + host_length);
321
	if (ret != 0) {
322
		close(*p_fd);
323
		return ret;
324
	}
325
326
	/* wait for the connection */
327
	/* read first 4 bytes of reply + 2 extra bytes we know will be there */
328
	ret = dcc_readx(*p_fd, buf, 6);
329
	if (ret != 0) {
330
		close(*p_fd);
331
		return ret;
332
	}
333
	if (buf[0] != 0x05 || buf[2] != 0x00) { /* version, reserved */
334
		rs_log_error("invalid proxy reply (version 0x%02x, reserved 0x%02x)",
335
				buf[0], buf[2]);
336
		close(*p_fd);
337
		return EXIT_CONNECT_FAILED;
338
	}
339
	if (buf[1] != 0x00) { /* reply */
340
		rs_log_error("proxy connection failed, reason=0x%02x", buf[1]);
341
		close(*p_fd);
342
		return EXIT_CONNECT_FAILED;
343
	}
344
345
	/* now read the remaining (packet size - 6) bytes */
346
	switch (buf[3]) { /* address type */
347
		case 0x01: skip_bytes = 4; break; /* IPv4 */
348
		case 0x03: skip_bytes = buf[4] + 1; /* hostname with length field */
349
		case 0x04: skip_bytes = 16; /* IPv6 */
350
		default:
351
		   rs_log_error("invalid proxy reply (address type 0x%02x)", buf[3]);
352
		   close(*p_fd);
353
		   return EXIT_CONNECT_FAILED;
354
	}
355
	ret = dcc_readx(*p_fd, buf, skip_bytes);
356
	if (ret != 0) {
357
		close(*p_fd);
358
		return ret;
359
	}
360
361
	return 0;
362
}
363
364
int dcc_connect_by_name(const char *host, int port, int *p_fd)
365
{
366
	const char *proxy;
367
368
	proxy = getenv("DISTCC_SOCKS_PROXY");
369
	if (proxy)
370
		return dcc_connect_via_socks5(host, port, p_fd, proxy);
371
	else
372
		return dcc_connect_by_name_real(host, port, p_fd);
373
}

Return to bug 537616