1 #include "links.h"
2 
3 /*
4 #define LOG_TRANSFER	"/tmp/log"
5 */
6 
7 #ifdef LOG_TRANSFER
log_data(unsigned char * data,int len)8 void log_data(unsigned char *data, int len)
9 {
10 	static int hlaseno = 0;
11 	int fd;
12 	if (!hlaseno) {
13 		printf("\n"ANSI_SET_BOLD"WARNING -- LOGGING NETWORK TRANSFERS !!!"ANSI_CLEAR_BOLD ANSI_BELL"\n");
14 		fflush(stdout);
15 		sleep(1);
16 		hlaseno = 1;
17 	}
18 	EINTRLOOP(fd, open(LOG_TRANSFER, O_WRONLY | O_APPEND | O_CREAT, 0600));
19 	if (fd != -1) {
20 		int rw;
21 		set_bin(fd);
22 		EINTRLOOP(rw, write(fd, data, len));
23 		EINTRLOOP(rw, close(fd));
24 	}
25 }
26 
27 #else
28 #define log_data(x, y)
29 #endif
30 
exception(struct connection * c)31 void exception(struct connection *c)
32 {
33 	setcstate(c, S_EXCEPT);
34 	retry_connection(c);
35 }
36 
close_socket(int * s)37 void close_socket(int *s)
38 {
39 	int rs;
40 	if (*s == -1) return;
41 	EINTRLOOP(rs, close(*s));
42 	set_handlers(*s, NULL, NULL, NULL, NULL);
43 	*s = -1;
44 }
45 
46 void connected(struct connection *);
47 
48 struct conn_info {
49 	void (*func)(struct connection *);
50 	ip addr;
51 	int port;
52 	int *sock;
53 };
54 
55 void dns_found(struct connection *, int);
56 
make_connection(struct connection * c,int port,int * sock,void (* func)(struct connection *))57 void make_connection(struct connection *c, int port, int *sock, void (*func)(struct connection *))
58 {
59 	int as;
60 	unsigned char *host;
61 	struct conn_info *b;
62 	if (!(host = get_host_name(c->url))) {
63 		setcstate(c, S_INTERNAL);
64 		abort_connection(c);
65 		return;
66 	}
67 	if (c->newconn)
68 		internal("already making a connection");
69 	b = mem_alloc(sizeof(struct conn_info));
70 	b->func = func;
71 	b->sock = sock;
72 	b->port = port;
73 	c->newconn = b;
74 	log_data("\nCONNECTION: ", 13);
75 	log_data(host, strlen(host));
76 	log_data("\n", 1);
77 	if (c->no_cache >= NC_RELOAD) as = find_host_no_cache(host, &b->addr, &c->dnsquery, (void(*)(void *, int))dns_found, c);
78 	else as = find_host(host, &b->addr, &c->dnsquery, (void(*)(void *, int))dns_found, c);
79 	mem_free(host);
80 	if (as) setcstate(c, S_DNS);
81 }
82 
get_pasv_socket(struct connection * c,int cc,int * sock,unsigned char * port)83 int get_pasv_socket(struct connection *c, int cc, int *sock, unsigned char *port)
84 {
85 	int s;
86 	int rs;
87 	struct sockaddr_in sa;
88 	struct sockaddr_in sb;
89 	socklen_t len = sizeof(sa);
90 	memset(&sa, 0, sizeof sa);
91 	memset(&sb, 0, sizeof sb);
92 	EINTRLOOP(rs, getsockname(cc, (struct sockaddr *)&sa, &len));
93 	if (rs) {
94 		e:
95 		setcstate(c, get_error_from_errno(errno));
96 		retry_connection(c);
97 		return -1;
98 	}
99 	EINTRLOOP(s, socket(PF_INET, SOCK_STREAM, IPPROTO_TCP));
100 	if (s == -1) goto e;
101 	set_nonblock(s);
102 	*sock = s;
103 	memcpy(&sb, &sa, sizeof(struct sockaddr_in));
104 	sb.sin_port = htons(0);
105 	EINTRLOOP(rs, bind(s, (struct sockaddr *)&sb, sizeof sb));
106 	if (rs) goto e;
107 	len = sizeof(sa);
108 	EINTRLOOP(rs, getsockname(s, (struct sockaddr *)&sa, &len));
109 	if (rs) goto e;
110 	EINTRLOOP(rs, listen(s, 1));
111 	if (rs) goto e;
112 	memcpy(port, &sa.sin_addr.s_addr, 4);
113 	memcpy(port + 4, &sa.sin_port, 2);
114 	return 0;
115 }
116 
117 #ifdef HAVE_SSL
ssl_want_read(struct connection * c)118 void ssl_want_read(struct connection *c)
119 {
120 	struct conn_info *b = c->newconn;
121 
122 	set_timeout(c);
123 
124 #ifdef SSL_OP_NO_TLSv1
125 	if (c->no_tls) SSL_set_options(c->ssl, SSL_OP_NO_TLSv1);
126 #endif
127 	switch (SSL_get_error(c->ssl, SSL_connect(c->ssl))) {
128 		case SSL_ERROR_NONE:
129 			c->newconn = NULL;
130 			b->func(c);
131 			mem_free(b);
132 			break;
133 		case SSL_ERROR_WANT_READ:
134 			set_handlers(*b->sock, (void(*)(void *))ssl_want_read, NULL, (void(*)(void *))exception, c);
135 			break;
136 		case SSL_ERROR_WANT_WRITE:
137 			set_handlers(*b->sock, NULL, (void(*)(void *))ssl_want_read, (void(*)(void *))exception, c);
138 			break;
139 		default:
140 			c->no_tls++;
141 			setcstate(c, S_SSL_ERROR);
142 			retry_connection(c);
143 			break;
144 	}
145 }
146 #endif
147 
dns_found(struct connection * c,int state)148 void dns_found(struct connection *c, int state)
149 {
150 	int s;
151 	int rs;
152 	struct conn_info *b = c->newconn;
153 	struct sockaddr_in sa;
154 	if (state) {
155 		setcstate(c, S_NO_DNS);
156 		abort_connection(c);
157 		return;
158 	}
159 	EINTRLOOP(s, socket(PF_INET, SOCK_STREAM, IPPROTO_TCP));
160 	if (s == -1) {
161 		setcstate(c, get_error_from_errno(errno));
162 		retry_connection(c);
163 		return;
164 	}
165 	set_nonblock(s);
166 	*b->sock = s;
167 	memset(&sa, 0, sizeof(struct sockaddr_in));
168 	sa.sin_family = AF_INET;
169 	sa.sin_addr.s_addr = b->addr;
170 	sa.sin_port = htons(b->port);
171 	EINTRLOOP(rs, connect(s, (struct sockaddr *)&sa, sizeof sa));
172 	if (rs) {
173 		if (errno != EALREADY && errno != EINPROGRESS) {
174 #ifdef BEOS
175 			if (errno == EWOULDBLOCK) errno = ETIMEDOUT;
176 #endif
177 			setcstate(c, get_error_from_errno(errno));
178 			retry_connection(c);
179 			return;
180 		}
181 		set_handlers(s, NULL, (void(*)(void *))connected, (void(*)(void *))exception, c);
182 		setcstate(c, S_CONN);
183 	} else {
184 		connected(c);
185 	}
186 }
187 
connected(struct connection * c)188 void connected(struct connection *c)
189 {
190 	struct conn_info *b = c->newconn;
191 	int err = 0;
192 	socklen_t len = sizeof(int);
193 	int rs;
194 #ifdef SO_ERROR
195 	errno = 0;
196 	EINTRLOOP(rs, getsockopt(*b->sock, SOL_SOCKET, SO_ERROR, (void *)&err, &len));
197 	if (!rs) {
198 		if (err >= 10000) err -= 10000;	/* Why does EMX return so large values? */
199 	} else {
200 		if (!(err = errno)) {
201 			setcstate(c, S_STATE);
202 			retry_connection(c);
203 			return;
204 		}
205 	}
206 	if (err > 0
207 #ifdef EISCONN
208 	    && err != EISCONN
209 #endif
210 	    ) {
211 #ifdef DOS
212 		if (err == EALREADY) err = ETIMEDOUT;
213 #endif
214 		setcstate(c, get_error_from_errno(err));
215 		retry_connection(c);
216 		return;
217 	}
218 #endif
219 	set_timeout(c);
220 #ifdef HAVE_SSL
221 	if (c->ssl) {
222 		c->ssl = getSSL();
223 		SSL_set_fd(c->ssl, *b->sock);
224 #ifdef SSL_OP_NO_TLSv1
225 		if (c->no_tls) SSL_set_options(c->ssl, SSL_OP_NO_TLSv1);
226 #endif
227 		switch (SSL_get_error(c->ssl, SSL_connect(c->ssl))) {
228 			case SSL_ERROR_WANT_READ:
229 				setcstate(c, S_SSL_NEG);
230 				set_handlers(*b->sock, (void(*)(void *))ssl_want_read, NULL, (void(*)(void *))exception, c);
231 				return;
232 			case SSL_ERROR_WANT_WRITE:
233 				setcstate(c, S_SSL_NEG);
234 				set_handlers(*b->sock, NULL, (void(*)(void *))ssl_want_read, (void(*)(void *))exception, c);
235 				return;
236 			case SSL_ERROR_NONE:
237 				break;
238 			default:
239 				c->no_tls++;
240 				setcstate(c, S_SSL_ERROR);
241 				retry_connection(c);
242 				return;
243 		}
244 	}
245 #endif
246 	c->newconn = NULL;
247 	b->func(c);
248 	mem_free(b);
249 }
250 
251 struct write_buffer {
252 	int sock;
253 	int len;
254 	int pos;
255 	void (*done)(struct connection *);
256 	unsigned char data[1];
257 };
258 
write_select(struct connection * c)259 void write_select(struct connection *c)
260 {
261 	struct write_buffer *wb;
262 	int wr;
263 	if (!(wb = c->buffer)) {
264 		internal("write socket has no buffer");
265 		setcstate(c, S_INTERNAL);
266 		abort_connection(c);
267 		return;
268 	}
269 	set_timeout(c);
270 	/*printf("ws: %d\n",wb->len-wb->pos);
271 	for (wr = wb->pos; wr < wb->len; wr++) printf("%c", wb->data[wr]);
272 	printf("-\n");*/
273 
274 #ifdef HAVE_SSL
275 	if(c->ssl) {
276 		if ((wr = SSL_write(c->ssl, wb->data + wb->pos, wb->len - wb->pos)) <= 0) {
277 			int err;
278 			if ((err = SSL_get_error(c->ssl, wr)) != SSL_ERROR_WANT_WRITE) {
279 				setcstate(c, wr ? (err == SSL_ERROR_SYSCALL ? get_error_from_errno(errno) : S_SSL_ERROR) : S_CANT_WRITE);
280 				if (!wr || err == SSL_ERROR_SYSCALL) retry_connection(c);
281 				else abort_connection(c);
282 				return;
283 			}
284 			else return;
285 		}
286 	} else
287 #endif
288 	{
289 		EINTRLOOP(wr, write(wb->sock, wb->data + wb->pos, wb->len - wb->pos));
290 		if (wr <= 0) {
291 #if defined(ATHEOS) || defined(DOS)
292 	/* Workaround for a bug in Syllable */
293 			if (wr && (errno == EAGAIN || errno == EWOULDBLOCK)) {
294 				return;
295 			}
296 #endif
297 			setcstate(c, wr ? get_error_from_errno(errno) : S_CANT_WRITE);
298 			retry_connection(c);
299 			return;
300 		}
301 	}
302 
303 	if ((wb->pos += wr) == wb->len) {
304 		void (*f)(struct connection *) = wb->done;
305 		c->buffer = NULL;
306 		set_handlers(wb->sock, NULL, NULL, NULL, NULL);
307 		mem_free(wb);
308 		f(c);
309 	}
310 }
311 
write_to_socket(struct connection * c,int s,unsigned char * data,int len,void (* write_func)(struct connection *))312 void write_to_socket(struct connection *c, int s, unsigned char *data, int len, void (*write_func)(struct connection *))
313 {
314 	struct write_buffer *wb;
315 	log_data(data, len);
316 	if ((unsigned)len > MAXINT - sizeof(struct write_buffer)) overalloc();
317 	wb = mem_alloc(sizeof(struct write_buffer) + len);
318 	wb->sock = s;
319 	wb->len = len;
320 	wb->pos = 0;
321 	wb->done = write_func;
322 	memcpy(wb->data, data, len);
323 	if (c->buffer) mem_free(c->buffer);
324 	c->buffer = wb;
325 	set_handlers(s, NULL, (void (*)(void *))write_select, (void (*)(void *))exception, c);
326 }
327 
328 #define READ_SIZE	64240
329 
read_select(struct connection * c)330 void read_select(struct connection *c)
331 {
332 	struct read_buffer *rb;
333 	int rd;
334 	if (!(rb = c->buffer)) {
335 		internal("read socket has no buffer");
336 		setcstate(c, S_INTERNAL);
337 		abort_connection(c);
338 		return;
339 	}
340 	set_handlers(rb->sock, NULL, NULL, NULL, NULL);
341 	if ((unsigned)rb->len > MAXINT - sizeof(struct read_buffer) - READ_SIZE) overalloc();
342 	rb = mem_realloc(rb, sizeof(struct read_buffer) + rb->len + READ_SIZE);
343 	c->buffer = rb;
344 
345 #ifdef HAVE_SSL
346 	if(c->ssl) {
347 		if ((rd = SSL_read(c->ssl, rb->data + rb->len, READ_SIZE)) <= 0) {
348 			int err;
349 			if ((err = SSL_get_error(c->ssl, rd)) == SSL_ERROR_WANT_READ) {
350 				read_from_socket(c, rb->sock, rb, rb->done);
351 				return;
352 			}
353 			if (rb->close && !rd) {
354 				rb->close = 2;
355 				rb->done(c, rb);
356 				return;
357 			}
358 			setcstate(c, rd ? (err == SSL_ERROR_SYSCALL ? get_error_from_errno(errno) : S_SSL_ERROR) : S_CANT_READ);
359 			/*mem_free(rb);*/
360 			if (!rd || err == SSL_ERROR_SYSCALL) retry_connection(c);
361 			else abort_connection(c);
362 			return;
363 		}
364 	} else
365 #endif
366 	{
367 		EINTRLOOP(rd, read(rb->sock, rb->data + rb->len, READ_SIZE));
368 		if (rd <= 0) {
369 			if (rb->close && !rd) {
370 				rb->close = 2;
371 				rb->done(c, rb);
372 				return;
373 			}
374 			setcstate(c, rd ? get_error_from_errno(errno) : S_CANT_READ);
375 			/*mem_free(rb);*/
376 			retry_connection(c);
377 			return;
378 		}
379 	}
380 	log_data(rb->data + rb->len, rd);
381 	rb->len += rd;
382 	rb->done(c, rb);
383 }
384 
alloc_read_buffer(struct connection * c)385 struct read_buffer *alloc_read_buffer(struct connection *c)
386 {
387 	struct read_buffer *rb;
388 	rb = mem_alloc(sizeof(struct read_buffer) + READ_SIZE);
389 	memset(rb, 0, sizeof(struct read_buffer));
390 	return rb;
391 }
392 
read_from_socket(struct connection * c,int s,struct read_buffer * buf,void (* read_func)(struct connection *,struct read_buffer *))393 void read_from_socket(struct connection *c, int s, struct read_buffer *buf, void (*read_func)(struct connection *, struct read_buffer *))
394 {
395 	buf->done = read_func;
396 	buf->sock = s;
397 	if (c->buffer && buf != c->buffer) mem_free(c->buffer);
398 	c->buffer = buf;
399 	set_handlers(s, (void (*)(void *))read_select, NULL, (void (*)(void *))exception, c);
400 }
401 
kill_buffer_data(struct read_buffer * rb,int n)402 void kill_buffer_data(struct read_buffer *rb, int n)
403 {
404 	if (n > rb->len || n < 0) {
405 		internal("called kill_buffer_data with bad value");
406 		rb->len = 0;
407 		return;
408 	}
409 	memmove(rb->data, rb->data + n, rb->len - n);
410 	rb->len -= n;
411 }
412