1 /* Copyright 2001,2002 Roger Dingledine, Matej Pfajfar. */
2 /* See LICENSE for licensing information */
9 extern or_options_t options
; /* command-line and config-file options */
11 /* Create a new buf of size MAX_BUF_SIZE. Write a pointer to it
12 * into *buf, write MAX_BUF_SIZE into *buflen, and initialize
13 * *buf_datalen to 0. Return 0.
15 int buf_new(char **buf
, int *buflen
, int *buf_datalen
) {
17 assert(buf
&& buflen
&& buf_datalen
);
19 *buf
= (char *)tor_malloc(MAX_BUF_SIZE
);
20 // memset(*buf,0,MAX_BUF_SIZE);
21 *buflen
= MAX_BUF_SIZE
;
27 void buf_free(char *buf
) {
31 /* read from socket s, writing onto buf+buf_datalen. If at_most is >= 0 then
32 * read at most 'at_most' bytes, and in any case don't read more than will fit based on buflen.
33 * If read() returns 0, set *reached_eof to 1 and return 0. If you want to tear
34 * down the connection return -1, else return the number of bytes read.
36 int read_to_buf(int s
, int at_most
, char **buf
, int *buflen
, int *buf_datalen
, int *reached_eof
) {
40 assert(buf
&& *buf
&& buflen
&& buf_datalen
&& reached_eof
&& (s
>=0));
42 /* this is the point where you would grow the buffer, if you want to */
44 if(at_most
< 0 || *buflen
- *buf_datalen
< at_most
)
45 at_most
= *buflen
- *buf_datalen
; /* take the min of the two */
46 /* (note that this only modifies at_most inside this function) */
49 return 0; /* we shouldn't read anything */
51 if(!options
.LinkPadding
&& at_most
> 10*sizeof(cell_t
)) {
52 /* if no linkpadding: do a rudimentary round-robin so one
53 * connection can't hog a thickpipe
55 at_most
= 10*(CELL_PAYLOAD_SIZE
- RELAY_HEADER_SIZE
);
56 /* XXX this still isn't perfect. now we read 10 relay data payloads per read --
57 * but if we're reading from a connection that speaks cells, we always
58 * read a partial cell from the network and can't process it yet. Good
59 * enough for now though. (And maybe best, to stress our code more.)
63 // log_fn(LOG_DEBUG,"reading at most %d bytes.",at_most);
64 read_result
= read(s
, *buf
+*buf_datalen
, at_most
);
65 if (read_result
< 0) {
66 if(errno
!=EAGAIN
) { /* it's a real error */
70 } else if (read_result
== 0) {
71 log_fn(LOG_DEBUG
,"Encountered eof");
74 } else { /* we read some bytes */
75 *buf_datalen
+= read_result
;
76 // log_fn(LOG_DEBUG,"Read %d bytes. %d on inbuf.",read_result, *buf_datalen);
81 int flush_buf(int s
, char **buf
, int *buflen
, int *buf_flushlen
, int *buf_datalen
) {
83 /* push from buf onto s
84 * then memmove to front of buf
85 * return -1 or how many bytes remain to be flushed */
89 assert(buf
&& *buf
&& buflen
&& buf_flushlen
&& buf_datalen
&& (s
>=0) && (*buf_flushlen
<= *buf_datalen
));
91 if(*buf_flushlen
== 0) /* nothing to flush */
94 /* this is the point where you would grow the buffer, if you want to */
96 write_result
= write(s
, *buf
, *buf_flushlen
);
97 if (write_result
< 0) {
98 if(errno
!=EAGAIN
) { /* it's a real error */
101 log_fn(LOG_DEBUG
,"write() would block, returning.");
104 *buf_datalen
-= write_result
;
105 *buf_flushlen
-= write_result
;
106 memmove(*buf
, *buf
+write_result
, *buf_datalen
);
107 // log_fn(LOG_DEBUG,"flushed %d bytes, %d ready to flush, %d remain.",
108 // write_result,*buf_flushlen,*buf_datalen);
109 return *buf_flushlen
;
113 int write_to_buf(char *string
, int string_len
,
114 char **buf
, int *buflen
, int *buf_datalen
) {
116 /* append string to buf (growing as needed, return -1 if "too big")
117 * return total number of bytes on the buf
120 assert(string
&& buf
&& *buf
&& buflen
&& buf_datalen
);
122 /* this is the point where you would grow the buffer, if you want to */
124 if (string_len
+ *buf_datalen
> *buflen
) { /* we're out of luck */
125 log_fn(LOG_DEBUG
, "buflen too small. Time to implement growing dynamic bufs.");
129 memcpy(*buf
+*buf_datalen
, string
, string_len
);
130 *buf_datalen
+= string_len
;
131 // log_fn(LOG_DEBUG,"added %d bytes to buf (now %d total).",string_len, *buf_datalen);
135 int fetch_from_buf(char *string
, int string_len
,
136 char **buf
, int *buflen
, int *buf_datalen
) {
138 /* if there are string_len bytes in buf, write them onto string,
139 * then memmove buf back (that is, remove them from buf).
141 * If there are not enough bytes on the buffer to fill string, return -1.
143 * Return the number of bytes still on the buffer. */
145 assert(string
&& buf
&& *buf
&& buflen
&& buf_datalen
);
147 /* this is the point where you would grow the buffer, if you want to */
149 if(string_len
> *buf_datalen
) /* we want too much. sorry. */
152 memcpy(string
,*buf
,string_len
);
153 *buf_datalen
-= string_len
;
154 memmove(*buf
, *buf
+string_len
, *buf_datalen
);
158 int find_on_inbuf(char *string
, int string_len
,
159 char *buf
, int buf_datalen
) {
160 /* find first instance of needle 'string' on haystack 'buf'. return how
161 * many bytes from the beginning of buf to the end of string.
162 * If it's not there, return -1.
166 char *last_possible
= buf
+ buf_datalen
- string_len
;
168 assert(string
&& string_len
> 0 && buf
);
170 if(buf_datalen
< string_len
)
173 for(location
= buf
; location
<= last_possible
; location
++)
174 if((*location
== *string
) && !memcmp(location
+1, string
+1, string_len
-1))
175 return location
-buf
+string_len
;