1 /* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar. */
2 /* See LICENSE for licensing information */
15 /* Size, in bytes, for newly allocated buffers. Should be a power of 2. */
16 #define INITIAL_BUF_SIZE (4*1024)
17 /* Maximum size, in bytes, for resized buffers. */
18 #define MAX_BUF_SIZE (1024*1024)
19 /* Size, in bytes, for minimum 'shrink' size for buffers. Buffers may start
20 * out smaller than this, but they will never autoshrink to less
22 #define MIN_BUF_SHRINK_SIZE (16*1024)
23 #define BUF_OK(b) ((b) && (b)->mem && (b)->datalen <= (b)->len)
25 /* Change a buffer's capacity. Must only be called when */
26 static INLINE
void buf_resize(buf_t
*buf
, size_t new_capacity
)
28 assert(buf
->datalen
<= new_capacity
);
30 buf
->mem
= tor_realloc(buf
->mem
, new_capacity
);
31 buf
->len
= new_capacity
;
34 /* If the buffer is not large enough to hold "capacity" bytes, resize
35 * it so that it can. (The new size will be a power of 2 times the old
38 static INLINE
int buf_ensure_capacity(buf_t
*buf
, size_t capacity
)
41 if (buf
->len
>= capacity
) /* Don't grow if we're already big enough. */
43 if (capacity
> MAX_BUF_SIZE
) /* Don't grow past the maximum. */
45 /* Find the smallest new_len equal to (2**X)*len for some X; such that
46 * new_len is at least capacity.
49 while (new_len
< capacity
)
51 /* Resize the buffer. */
52 log_fn(LOG_DEBUG
,"Growing buffer from %d to %d bytes.",
53 (int)buf
->len
, (int)new_len
);
54 buf_resize(buf
,new_len
);
58 /* If the buffer is at least 2*MIN_BUF_SHRINK_SIZE bytes in capacity,
59 * and if the buffer is less than 1/4 full, shrink the buffer until
60 * one of the above no longer holds. (We shrink the buffer by
61 * dividing by powers of 2.)
63 static INLINE
void buf_shrink_if_underfull(buf_t
*buf
) {
65 /* If the buffer is at least .25 full, or if shrinking the buffer would
66 * put it onder MIN_BUF_SHRINK_SIZE, don't do it. */
67 if (buf
->datalen
>= buf
->len
/4 || buf
->len
< 2*MIN_BUF_SHRINK_SIZE
)
69 /* Shrink new_len by powers of 2 until: datalen is at least 1/4 of
70 * new_len, OR shrinking new_len more would put it under
71 * MIN_BUF_SHRINK_SIZE.
73 new_len
= buf
->len
/ 2;
74 while (buf
->datalen
< new_len
/4 && new_len
/2 > MIN_BUF_SHRINK_SIZE
)
76 log_fn(LOG_DEBUG
,"Shrinking buffer from %d to %d bytes.",
77 (int)buf
->len
, (int)new_len
);
78 buf_resize(buf
, new_len
);
81 /* Remove the first 'n' bytes from buf.
83 static INLINE
void buf_remove_from_front(buf_t
*buf
, size_t n
) {
84 assert(buf
->datalen
>= n
);
86 memmove(buf
->mem
, buf
->mem
+n
, buf
->datalen
);
87 buf_shrink_if_underfull(buf
);
90 /* Find the first instance of str on buf. If none exists, return -1.
91 * Otherwise, return index of the first character in buf _after_ the
92 * first instance of str.
94 static int find_str_in_str(const char *str
, int str_len
,
95 const char *buf
, int buf_len
)
98 const char *last_possible
= buf
+ buf_len
- str_len
;
100 assert(str
&& str_len
> 0 && buf
);
102 if(buf_len
< str_len
)
105 for(location
= buf
; location
<= last_possible
; location
++)
106 if((*location
== *str
) && !memcmp(location
+1, str
+1, str_len
-1))
107 return location
-buf
+str_len
;
112 int find_on_inbuf(char *string
, int string_len
, buf_t
*buf
) {
113 return find_str_in_str(string
, string_len
, buf
->mem
, buf
->datalen
);
116 /* Create and return a new buf of size 'size'
118 buf_t
*buf_new_with_capacity(size_t size
) {
120 buf
= (buf_t
*)tor_malloc(sizeof(buf_t
));
121 buf
->mem
= (char *)tor_malloc(size
);
124 // memset(buf->mem,0,size);
132 return buf_new_with_capacity(INITIAL_BUF_SIZE
);
136 size_t buf_datalen(const buf_t
*buf
)
141 size_t buf_capacity(const buf_t
*buf
)
146 const char *_buf_peek_raw_buffer(const buf_t
*buf
)
151 void buf_free(buf_t
*buf
) {
152 assert(buf
&& buf
->mem
);
157 /* read from socket s, writing onto end of buf.
158 * read at most 'at_most' bytes, and in any case don't read more than will fit based on buflen.
159 * If read() returns 0, set *reached_eof to 1 and return 0. If you want to tear
160 * down the connection return -1, else return the number of bytes read.
162 int read_to_buf(int s
, int at_most
, buf_t
*buf
, int *reached_eof
) {
169 assert(BUF_OK(buf
) && reached_eof
&& (s
>=0));
171 if (buf_ensure_capacity(buf
,buf
->datalen
+at_most
))
174 if(at_most
> buf
->len
- buf
->datalen
)
175 at_most
= buf
->len
- buf
->datalen
; /* take the min of the two */
178 return 0; /* we shouldn't read anything */
180 // log_fn(LOG_DEBUG,"reading at most %d bytes.",at_most);
181 read_result
= read(s
, buf
->mem
+buf
->datalen
, at_most
);
182 if (read_result
< 0) {
183 if(!ERRNO_EAGAIN(errno
)) { /* it's a real error */
187 e
= correct_socket_errno(s
);
188 if(!ERRNO_EAGAIN(e
)) { /* no, it *is* a real error! */
193 } else if (read_result
== 0) {
194 log_fn(LOG_DEBUG
,"Encountered eof");
197 } else { /* we read some bytes */
198 buf
->datalen
+= read_result
;
199 log_fn(LOG_DEBUG
,"Read %d bytes. %d on inbuf.",read_result
,
205 int read_to_buf_tls(tor_tls
*tls
, int at_most
, buf_t
*buf
) {
207 assert(tls
&& BUF_OK(buf
));
209 if (buf_ensure_capacity(buf
, at_most
+buf
->datalen
))
212 if (at_most
> buf
->len
- buf
->datalen
)
213 at_most
= buf
->len
- buf
->datalen
;
218 r
= tor_tls_read(tls
, buf
->mem
+buf
->datalen
, at_most
);
222 log_fn(LOG_DEBUG
,"Read %d bytes. %d on inbuf.",r
, (int)buf
->datalen
);
226 int flush_buf(int s
, buf_t
*buf
, int *buf_flushlen
)
229 /* push from buf onto s
230 * then memmove to front of buf
231 * return -1 or how many bytes remain to be flushed */
238 assert(BUF_OK(buf
) && buf_flushlen
&& (s
>=0) && (*buf_flushlen
<= buf
->datalen
));
240 if(*buf_flushlen
== 0) /* nothing to flush */
243 write_result
= write(s
, buf
->mem
, *buf_flushlen
);
244 if (write_result
< 0) {
245 if(!ERRNO_EAGAIN(errno
)) { /* it's a real error */
249 e
= correct_socket_errno(s
);
250 if(!ERRNO_EAGAIN(e
)) { /* no, it *is* a real error! */
254 log_fn(LOG_DEBUG
,"write() would block, returning.");
257 *buf_flushlen
-= write_result
;
258 buf_remove_from_front(buf
, write_result
);
259 log_fn(LOG_DEBUG
,"%d: flushed %d bytes, %d ready to flush, %d remain.",
260 s
,write_result
,*buf_flushlen
,(int)buf
->datalen
);
262 return *buf_flushlen
;
263 /* XXX USE_TLS should change to return write_result like any sane function would */
267 int flush_buf_tls(tor_tls
*tls
, buf_t
*buf
, int *buf_flushlen
)
270 assert(tls
&& BUF_OK(buf
) && buf_flushlen
);
272 /* we want to let tls write even if flushlen is zero, because it might
273 * have a partial record pending */
274 r
= tor_tls_write(tls
, buf
->mem
, *buf_flushlen
);
279 buf_remove_from_front(buf
, r
);
280 log_fn(LOG_DEBUG
,"flushed %d bytes, %d ready to flush, %d remain.",
281 r
,*buf_flushlen
,(int)buf
->datalen
);
285 int write_to_buf(const char *string
, int string_len
, buf_t
*buf
) {
287 /* append string to buf (growing as needed, return -1 if "too big")
288 * return total number of bytes on the buf
291 assert(string
&& BUF_OK(buf
));
293 if (buf_ensure_capacity(buf
, buf
->datalen
+string_len
))
294 log_fn(LOG_WARN
, "buflen too small, can't hold %d bytes.",buf
->datalen
+string_len
);
297 memcpy(buf
->mem
+buf
->datalen
, string
, string_len
);
298 buf
->datalen
+= string_len
;
299 log_fn(LOG_DEBUG
,"added %d bytes to buf (now %d total).",string_len
, (int)buf
->datalen
);
303 int fetch_from_buf(char *string
, int string_len
, buf_t
*buf
) {
305 /* There must be string_len bytes in buf; write them onto string,
306 * then memmove buf back (that is, remove them from buf).
308 * Return the number of bytes still on the buffer. */
310 assert(string
&& BUF_OK(buf
));
311 assert(string_len
<= buf
->datalen
); /* make sure we don't ask for too much */
313 memcpy(string
,buf
->mem
,string_len
);
314 buf_remove_from_front(buf
, string_len
);
318 /* There is a (possibly incomplete) http statement on *buf, of the
319 * form "%s\r\n\r\n%s", headers, body.
320 * If a) the headers include a Content-Length field and all bytes in
321 * the body are present, or b) there's no Content-Length field and
322 * all headers are present, then:
323 * copy headers and body into the supplied args (and null terminate
324 * them), remove them from buf, and return 1.
325 * (If headers or body is NULL, discard that part of the buf.)
326 * If a headers or body doesn't fit in the arg, return -1.
328 * Else, change nothing and return 0.
330 int fetch_from_buf_http(buf_t
*buf
,
331 char *headers_out
, int max_headerlen
,
332 char *body_out
, int max_bodylen
) {
333 char *headers
, *body
;
335 int headerlen
, bodylen
, contentlen
;
340 i
= find_on_inbuf("\r\n\r\n", 4, buf
);
342 log_fn(LOG_DEBUG
,"headers not all here yet.");
346 headerlen
= body
-headers
; /* includes the CRLFCRLF */
347 bodylen
= buf
->datalen
- headerlen
;
348 log_fn(LOG_DEBUG
,"headerlen %d, bodylen %d.",headerlen
,bodylen
);
350 if(headers_out
&& max_headerlen
<= headerlen
) {
351 log_fn(LOG_WARN
,"headerlen %d larger than %d. Failing.", headerlen
, max_headerlen
-1);
354 if(body_out
&& max_bodylen
<= bodylen
) {
355 log_fn(LOG_WARN
,"bodylen %d larger than %d. Failing.", bodylen
, max_bodylen
-1);
359 #define CONTENT_LENGTH "\r\nContent-Length: "
360 i
= find_str_in_str(CONTENT_LENGTH
, strlen(CONTENT_LENGTH
),
363 contentlen
= atoi(headers
+i
);
364 /* XXX What if content-length is malformed? */
365 log_fn(LOG_DEBUG
,"Got a contentlen of %d.",contentlen
);
366 if(bodylen
< contentlen
) {
367 log_fn(LOG_DEBUG
,"body not all here yet.");
368 return 0; /* not all there yet */
370 bodylen
= contentlen
;
371 log_fn(LOG_DEBUG
,"bodylen reduced to %d.",bodylen
);
373 /* all happy. copy into the appropriate places, and return 1 */
375 memcpy(headers_out
,buf
->mem
,headerlen
);
376 headers_out
[headerlen
] = 0; /* null terminate it */
379 memcpy(body_out
,buf
->mem
+headerlen
,bodylen
);
380 body_out
[bodylen
] = 0; /* null terminate it */
382 buf_remove_from_front(buf
, headerlen
+bodylen
);
386 /* There is a (possibly incomplete) socks handshake on buf, of one
388 * socks4: "socksheader username\0"
389 * socks4a: "socksheader username\0 destaddr\0"
390 * socks5 phase one: "version #methods methods"
391 * socks5 phase two: "version command 0 addresstype..."
392 * If it's a complete and valid handshake, and destaddr fits in
393 * MAX_SOCKS_ADDR_LEN bytes, then pull the handshake off the buf,
394 * assign to *req, and return 1.
395 * If it's invalid or too big, return -1.
396 * Else it's not all there yet, leave buf alone and return 0.
397 * If you want to specify the socks reply, write it into *reply
398 * and set *replylen, else leave *replylen alone.
399 * If returning 0 or -1, *addr_out and *port_out are undefined.
401 int fetch_from_buf_socks(buf_t
*buf
, socks_request_t
*req
) {
405 enum {socks4
, socks4a
} socks4_prot
= socks4a
;
406 char *next
, *startaddr
;
409 if(buf
->datalen
< 2) /* version and another byte */
411 switch(*(buf
->mem
)) { /* which version of socks? */
415 if(req
->socks_version
!= 5) { /* we need to negotiate a method */
416 unsigned char nummethods
= (unsigned char)*(buf
->mem
+1);
417 assert(!req
->socks_version
);
418 log_fn(LOG_DEBUG
,"socks5: learning offered methods");
419 if(buf
->datalen
< 2+nummethods
)
421 if(!nummethods
|| !memchr(buf
->mem
+2, 0, nummethods
)) {
422 log_fn(LOG_WARN
,"socks5: offered methods don't include 'no auth'. Rejecting.");
423 req
->replylen
= 2; /* 2 bytes of response */
424 req
->reply
[0] = 5; /* socks5 reply */
425 req
->reply
[1] = 0xFF; /* reject all methods */
428 buf_remove_from_front(buf
,2+nummethods
);/* remove packet from buf */
430 req
->replylen
= 2; /* 2 bytes of response */
431 req
->reply
[0] = 5; /* socks5 reply */
432 req
->reply
[1] = 0; /* choose the 'no auth' method */
433 req
->socks_version
= 5; /* remember that we've already negotiated auth */
434 log_fn(LOG_DEBUG
,"socks5: accepted method 0");
437 /* we know the method; read in the request */
438 log_fn(LOG_DEBUG
,"socks5: checking request");
439 if(buf
->datalen
< 8) /* basic info plus >=2 for addr plus 2 for port */
440 return 0; /* not yet */
441 if(*(buf
->mem
+1) != 1) { /* not a connect? we don't support it. */
442 log_fn(LOG_WARN
,"socks5: command %d not '1'.",*(buf
->mem
+1));
445 switch(*(buf
->mem
+3)) { /* address type */
446 case 1: /* IPv4 address */
447 log_fn(LOG_DEBUG
,"socks5: ipv4 address type");
448 if(buf
->datalen
< 10) /* ip/port there? */
449 return 0; /* not yet */
450 destip
= ntohl(*(uint32_t*)(buf
->mem
+4));
451 in
.s_addr
= htonl(destip
);
452 tmpbuf
= inet_ntoa(in
);
453 if(strlen(tmpbuf
)+1 > MAX_SOCKS_ADDR_LEN
) {
454 log_fn(LOG_WARN
,"socks5 IP takes %d bytes, which doesn't fit in %d",
455 strlen(tmpbuf
)+1,MAX_SOCKS_ADDR_LEN
);
458 strcpy(req
->address
,tmpbuf
);
459 req
->port
= ntohs(*(uint16_t*)(buf
->mem
+8));
460 buf_remove_from_front(buf
, 10);
463 log_fn(LOG_DEBUG
,"socks5: fqdn address type");
464 len
= (unsigned char)*(buf
->mem
+4);
465 if(buf
->datalen
< 7+len
) /* addr/port there? */
466 return 0; /* not yet */
467 if(len
+1 > MAX_SOCKS_ADDR_LEN
) {
468 log_fn(LOG_WARN
,"socks5 hostname is %d bytes, which doesn't fit in %d",
469 len
+1,MAX_SOCKS_ADDR_LEN
);
472 memcpy(req
->address
,buf
->mem
+5,len
);
473 req
->address
[len
] = 0;
474 req
->port
= ntohs(*(uint16_t*)(buf
->mem
+5+len
));
475 buf_remove_from_front(buf
, 5+len
+2);
477 default: /* unsupported */
478 log_fn(LOG_WARN
,"socks5: unsupported address type %d",*(buf
->mem
+3));
484 req
->socks_version
= 4;
485 if(buf
->datalen
< SOCKS4_NETWORK_LEN
) /* basic info available? */
486 return 0; /* not yet */
488 if(*(buf
->mem
+1) != 1) { /* not a connect? we don't support it. */
489 log_fn(LOG_WARN
,"socks4: command %d not '1'.",*(buf
->mem
+1));
493 req
->port
= ntohs(*(uint16_t*)(buf
->mem
+2));
494 destip
= ntohl(*(uint32_t*)(buf
->mem
+4));
495 if(!req
->port
|| !destip
) {
496 log_fn(LOG_WARN
,"socks4: Port or DestIP is zero.");
500 log_fn(LOG_DEBUG
,"socks4: destip not in form 0.0.0.x.");
501 in
.s_addr
= htonl(destip
);
502 tmpbuf
= inet_ntoa(in
);
503 if(strlen(tmpbuf
)+1 > MAX_SOCKS_ADDR_LEN
) {
504 log_fn(LOG_WARN
,"socks4 addr (%d bytes) too long.", strlen(tmpbuf
));
507 log_fn(LOG_DEBUG
,"socks4: successfully read destip (%s)", tmpbuf
);
508 socks4_prot
= socks4
;
511 next
= memchr(buf
->mem
+SOCKS4_NETWORK_LEN
, 0, buf
->datalen
);
513 log_fn(LOG_DEBUG
,"Username not here yet.");
518 if(socks4_prot
== socks4a
) {
519 next
= memchr(startaddr
, 0, buf
->mem
+buf
->datalen
-startaddr
);
521 log_fn(LOG_DEBUG
,"Destaddr not here yet.");
524 if(MAX_SOCKS_ADDR_LEN
<= next
-startaddr
) {
525 log_fn(LOG_WARN
,"Destaddr too long.");
529 log_fn(LOG_DEBUG
,"Everything is here. Success.");
530 strcpy(req
->address
, socks4_prot
== socks4
? tmpbuf
: startaddr
);
531 buf_remove_from_front(buf
, next
-buf
->mem
+1); /* next points to the final \0 on inbuf */
534 default: /* version is not socks4 or socks5 */
535 log_fn(LOG_WARN
,"Socks version %d not recognized. (Tor is not an httpd proxy.)",*(buf
->mem
));