iteed.c - teed - A multiplex relay tee(1) daemon. Err bitreich.org 70 hgit clone git://bitreich.org/teed git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/teed URL:git://bitreich.org/teed git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/teed bitreich.org 70 1Log /scm/teed/log.gph bitreich.org 70 1Files /scm/teed/files.gph bitreich.org 70 1Refs /scm/teed/refs.gph bitreich.org 70 1Tags /scm/teed/tag bitreich.org 70 1README /scm/teed/file/README.md.gph bitreich.org 70 1LICENSE /scm/teed/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 iteed.c (5223B) Err bitreich.org 70 i--- Err bitreich.org 70 i 1 /* Err bitreich.org 70 i 2 * See LICENSE file for license information. Err bitreich.org 70 i 3 * Err bitreich.org 70 i 4 * Copy me if you can. Err bitreich.org 70 i 5 * by 20h Err bitreich.org 70 i 6 */ Err bitreich.org 70 i 7 Err bitreich.org 70 i 8 #include Err bitreich.org 70 i 9 #include Err bitreich.org 70 i 10 #include Err bitreich.org 70 i 11 #include Err bitreich.org 70 i 12 #include Err bitreich.org 70 i 13 #include Err bitreich.org 70 i 14 #include Err bitreich.org 70 i 15 #include Err bitreich.org 70 i 16 #include Err bitreich.org 70 i 17 #include Err bitreich.org 70 i 18 Err bitreich.org 70 i 19 volatile sig_atomic_t isrunning = 1; Err bitreich.org 70 i 20 Err bitreich.org 70 i 21 void * Err bitreich.org 70 i 22 memdup(void *p, int l) Err bitreich.org 70 i 23 { Err bitreich.org 70 i 24 char *ret; Err bitreich.org 70 i 25 Err bitreich.org 70 i 26 ret = calloc(1, l); Err bitreich.org 70 i 27 if (ret == NULL) { Err bitreich.org 70 i 28 perror("calloc"); Err bitreich.org 70 i 29 exit(1); Err bitreich.org 70 i 30 } Err bitreich.org 70 i 31 memcpy(ret, p, l); Err bitreich.org 70 i 32 Err bitreich.org 70 i 33 return (void *)ret; Err bitreich.org 70 i 34 } Err bitreich.org 70 i 35 Err bitreich.org 70 i 36 typedef struct llist llist; Err bitreich.org 70 i 37 struct llist { Err bitreich.org 70 i 38 llist *prev; Err bitreich.org 70 i 39 llist *next; Err bitreich.org 70 i 40 int dlen; Err bitreich.org 70 i 41 void *data; Err bitreich.org 70 i 42 }; Err bitreich.org 70 i 43 Err bitreich.org 70 i 44 #define forllist(list, elem) for (elem = list;\ Err bitreich.org 70 i 45 elem; elem = elem->next) Err bitreich.org 70 i 46 Err bitreich.org 70 i 47 void Err bitreich.org 70 i 48 closeallfds(llist *fds) Err bitreich.org 70 i 49 { Err bitreich.org 70 i 50 llist *e; Err bitreich.org 70 i 51 Err bitreich.org 70 i 52 forllist(fds, e) Err bitreich.org 70 i 53 close(*(int *)e->data); Err bitreich.org 70 i 54 } Err bitreich.org 70 i 55 Err bitreich.org 70 i 56 void Err bitreich.org 70 i 57 llist_free1(llist *l) Err bitreich.org 70 i 58 { Err bitreich.org 70 i 59 if (l == NULL) Err bitreich.org 70 i 60 return; Err bitreich.org 70 i 61 free(l->data); Err bitreich.org 70 i 62 l->data = NULL; Err bitreich.org 70 i 63 l->next = NULL; Err bitreich.org 70 i 64 l->prev = NULL; Err bitreich.org 70 i 65 free(l); Err bitreich.org 70 i 66 } Err bitreich.org 70 i 67 Err bitreich.org 70 i 68 void Err bitreich.org 70 i 69 llist_free(llist *l) Err bitreich.org 70 i 70 { Err bitreich.org 70 i 71 llist *tl; Err bitreich.org 70 i 72 Err bitreich.org 70 i 73 while (l != NULL) { Err bitreich.org 70 i 74 tl = l->next; Err bitreich.org 70 i 75 llist_free1(l); Err bitreich.org 70 i 76 l = tl; Err bitreich.org 70 i 77 } Err bitreich.org 70 i 78 } Err bitreich.org 70 i 79 Err bitreich.org 70 i 80 llist * Err bitreich.org 70 i 81 llist_new(llist *prev, llist *next, void *data, int len) Err bitreich.org 70 i 82 { Err bitreich.org 70 i 83 llist *ret; Err bitreich.org 70 i 84 Err bitreich.org 70 i 85 ret = calloc(1, sizeof(llist)); Err bitreich.org 70 i 86 if (ret == NULL) { Err bitreich.org 70 i 87 perror("calloc"); Err bitreich.org 70 i 88 exit(1); Err bitreich.org 70 i 89 } Err bitreich.org 70 i 90 ret->prev = prev; Err bitreich.org 70 i 91 ret->next = next; Err bitreich.org 70 i 92 if (data != NULL) { Err bitreich.org 70 i 93 ret->data = memdup(data, len); Err bitreich.org 70 i 94 ret->dlen = len; Err bitreich.org 70 i 95 } else { Err bitreich.org 70 i 96 ret->data = NULL; Err bitreich.org 70 i 97 ret->dlen = 0; Err bitreich.org 70 i 98 } Err bitreich.org 70 i 99 Err bitreich.org 70 i 100 return ret; Err bitreich.org 70 i 101 } Err bitreich.org 70 i 102 Err bitreich.org 70 i 103 int Err bitreich.org 70 i 104 llist_len(llist *l) Err bitreich.org 70 i 105 { Err bitreich.org 70 i 106 int llistl = 0; Err bitreich.org 70 i 107 for (;l != NULL; l = l->next) Err bitreich.org 70 i 108 llistl++; Err bitreich.org 70 i 109 return llistl; Err bitreich.org 70 i 110 } Err bitreich.org 70 i 111 Err bitreich.org 70 i 112 llist * Err bitreich.org 70 i 113 llist_put(llist *l, void *data, int len) Err bitreich.org 70 i 114 { Err bitreich.org 70 i 115 llist *ol; Err bitreich.org 70 i 116 Err bitreich.org 70 i 117 if (l == NULL) Err bitreich.org 70 i 118 return llist_new(NULL, NULL, data, len); Err bitreich.org 70 i 119 Err bitreich.org 70 i 120 ol = l; Err bitreich.org 70 i 121 for (; l->next; l = l->next); Err bitreich.org 70 i 122 l->next = llist_new(l, NULL, data, len); Err bitreich.org 70 i 123 Err bitreich.org 70 i 124 return ol; Err bitreich.org 70 i 125 } Err bitreich.org 70 i 126 Err bitreich.org 70 i 127 llist * Err bitreich.org 70 i 128 llist_del(llist **l, llist *e) Err bitreich.org 70 i 129 { Err bitreich.org 70 i 130 llist *enext, *eprev; Err bitreich.org 70 i 131 Err bitreich.org 70 i 132 enext = e->next; Err bitreich.org 70 i 133 eprev = e->prev; Err bitreich.org 70 i 134 if (enext != NULL) Err bitreich.org 70 i 135 enext->prev = eprev; Err bitreich.org 70 i 136 if (eprev != NULL) Err bitreich.org 70 i 137 eprev->next = enext; Err bitreich.org 70 i 138 llist_free1(e); Err bitreich.org 70 i 139 Err bitreich.org 70 i 140 if (*l == e) Err bitreich.org 70 i 141 *l = enext; Err bitreich.org 70 i 142 Err bitreich.org 70 i 143 if (eprev != NULL) Err bitreich.org 70 i 144 return eprev; Err bitreich.org 70 i 145 if (enext != NULL) Err bitreich.org 70 i 146 return enext; Err bitreich.org 70 i 147 return NULL; Err bitreich.org 70 i 148 } Err bitreich.org 70 i 149 Err bitreich.org 70 i 150 void Err bitreich.org 70 i 151 sighandler(int signo) Err bitreich.org 70 i 152 { Err bitreich.org 70 i 153 switch (signo) { Err bitreich.org 70 i 154 case SIGINT: Err bitreich.org 70 i 155 case SIGTERM: Err bitreich.org 70 i 156 isrunning = 0; Err bitreich.org 70 i 157 break; Err bitreich.org 70 i 158 } Err bitreich.org 70 i 159 } Err bitreich.org 70 i 160 Err bitreich.org 70 i 161 void Err bitreich.org 70 i 162 initsignals(void) Err bitreich.org 70 i 163 { Err bitreich.org 70 i 164 signal(SIGPIPE, SIG_IGN); Err bitreich.org 70 i 165 signal(SIGINT, sighandler); Err bitreich.org 70 i 166 signal(SIGTERM, sighandler); Err bitreich.org 70 i 167 } Err bitreich.org 70 i 168 Err bitreich.org 70 i 169 int Err bitreich.org 70 i 170 main(int argc, char *argv[]) Err bitreich.org 70 i 171 { Err bitreich.org 70 i 172 int on, i, maxsfd, afd, rval, recvl, Err bitreich.org 70 i 173 sendl, sent, lfd; Err bitreich.org 70 i 174 struct sockaddr_un saddrs[2], clt; Err bitreich.org 70 i 175 char *bindpaths[2] = {"in", "out"}, Err bitreich.org 70 i 176 recvbuf[4*1024], Err bitreich.org 70 i 177 *sendbufi; Err bitreich.org 70 i 178 llist *wfds, *rfds, *lfds, *e, *qe; Err bitreich.org 70 i 179 socklen_t saddrlen, cltlen; Err bitreich.org 70 i 180 fd_set fdset; Err bitreich.org 70 i 181 struct timespec timeout; Err bitreich.org 70 i 182 Err bitreich.org 70 i 183 initsignals(); Err bitreich.org 70 i 184 Err bitreich.org 70 i 185 rval = 1; Err bitreich.org 70 i 186 rfds = NULL; Err bitreich.org 70 i 187 wfds = NULL; Err bitreich.org 70 i 188 lfds = NULL; Err bitreich.org 70 i 189 Err bitreich.org 70 i 190 on = 1; Err bitreich.org 70 i 191 for (i = 0; i < 2; i++) { Err bitreich.org 70 i 192 lfd = socket(AF_UNIX, SOCK_STREAM, 0); Err bitreich.org 70 i 193 if (lfd < 0) { Err bitreich.org 70 i 194 perror("socket"); Err bitreich.org 70 i 195 goto stop_serving; Err bitreich.org 70 i 196 } Err bitreich.org 70 i 197 if (setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, Err bitreich.org 70 i 198 &on, sizeof(on)) < 0) { Err bitreich.org 70 i 199 perror("setsockopt"); Err bitreich.org 70 i 200 goto stop_serving; Err bitreich.org 70 i 201 } Err bitreich.org 70 i 202 Err bitreich.org 70 i 203 if (access(bindpaths[i], F_OK) == 0) { Err bitreich.org 70 i 204 if (remove(bindpaths[i]) < 0) { Err bitreich.org 70 i 205 perror("remove"); Err bitreich.org 70 i 206 goto stop_serving; Err bitreich.org 70 i 207 } Err bitreich.org 70 i 208 } Err bitreich.org 70 i 209 Err bitreich.org 70 i 210 saddrs[i].sun_family = AF_UNIX; Err bitreich.org 70 i 211 strncpy(saddrs[i].sun_path, bindpaths[i], Err bitreich.org 70 i 212 sizeof(bindpaths[i])-1); Err bitreich.org 70 i 213 saddrlen = sizeof(saddrs[i]); Err bitreich.org 70 i 214 Err bitreich.org 70 i 215 if (bind(lfd, (struct sockaddr *)&saddrs[i], saddrlen) < 0) { Err bitreich.org 70 i 216 perror("bind"); Err bitreich.org 70 i 217 goto stop_serving; Err bitreich.org 70 i 218 } Err bitreich.org 70 i 219 Err bitreich.org 70 i 220 if (chmod(bindpaths[i], 0775) < 0) { Err bitreich.org 70 i 221 perror("chmod"); Err bitreich.org 70 i 222 goto stop_serving; Err bitreich.org 70 i 223 } Err bitreich.org 70 i 224 Err bitreich.org 70 i 225 if (listen(lfd, 255) < 0) { Err bitreich.org 70 i 226 perror("listen"); Err bitreich.org 70 i 227 goto stop_serving; Err bitreich.org 70 i 228 } Err bitreich.org 70 i 229 Err bitreich.org 70 i 230 lfds = llist_put(lfds, &lfd, sizeof(lfd)); Err bitreich.org 70 i 231 } Err bitreich.org 70 i 232 Err bitreich.org 70 i 233 timeout.tv_sec = 1; Err bitreich.org 70 i 234 timeout.tv_nsec = 0; Err bitreich.org 70 i 235 for (;isrunning;) { Err bitreich.org 70 i 236 maxsfd = 0; Err bitreich.org 70 i 237 FD_ZERO(&fdset); Err bitreich.org 70 i 238 forllist(lfds, e) { Err bitreich.org 70 i 239 FD_SET(*(int *)e->data, &fdset); Err bitreich.org 70 i 240 if (*(int *)e->data > maxsfd) Err bitreich.org 70 i 241 maxsfd = *(int *)e->data; Err bitreich.org 70 i 242 } Err bitreich.org 70 i 243 forllist(rfds, e) { Err bitreich.org 70 i 244 FD_SET(*(int *)e->data, &fdset); Err bitreich.org 70 i 245 if (*(int *)e->data > maxsfd) Err bitreich.org 70 i 246 maxsfd = *(int *)e->data; Err bitreich.org 70 i 247 } Err bitreich.org 70 i 248 Err bitreich.org 70 i 249 if (pselect(maxsfd+1, &fdset, NULL, NULL, &timeout, NULL) < 0) { Err bitreich.org 70 i 250 if (errno == EINTR) Err bitreich.org 70 i 251 continue; Err bitreich.org 70 i 252 perror("pselect"); Err bitreich.org 70 i 253 goto stop_serving; Err bitreich.org 70 i 254 } Err bitreich.org 70 i 255 Err bitreich.org 70 i 256 i = -1; Err bitreich.org 70 i 257 forllist(lfds, e) { Err bitreich.org 70 i 258 i++; Err bitreich.org 70 i 259 if (FD_ISSET(*(int *)e->data, &fdset)) { Err bitreich.org 70 i 260 cltlen = sizeof(clt); Err bitreich.org 70 i 261 afd = accept(*(int *)e->data, Err bitreich.org 70 i 262 (struct sockaddr *)&clt, Err bitreich.org 70 i 263 &cltlen); Err bitreich.org 70 i 264 if (afd < 0 && errno != ECONNABORTED Err bitreich.org 70 i 265 && errno != EINTR) { Err bitreich.org 70 i 266 perror("accept"); Err bitreich.org 70 i 267 goto stop_serving; Err bitreich.org 70 i 268 } Err bitreich.org 70 i 269 Err bitreich.org 70 i 270 if (i == 0) { Err bitreich.org 70 i 271 rfds = llist_put(rfds, &afd, Err bitreich.org 70 i 272 sizeof(afd)); Err bitreich.org 70 i 273 } else { Err bitreich.org 70 i 274 wfds = llist_put(wfds, &afd, Err bitreich.org 70 i 275 sizeof(afd)); Err bitreich.org 70 i 276 } Err bitreich.org 70 i 277 } Err bitreich.org 70 i 278 } Err bitreich.org 70 i 279 Err bitreich.org 70 i 280 forllist(rfds, e) { Err bitreich.org 70 i 281 if (FD_ISSET(*(int *)e->data, &fdset)) { Err bitreich.org 70 i 282 recvl = read(*(int *)e->data, recvbuf, Err bitreich.org 70 i 283 sizeof(recvbuf)); Err bitreich.org 70 i 284 if (recvl <= 0) { Err bitreich.org 70 i 285 close(*(int *)e->data); Err bitreich.org 70 i 286 e = llist_del(&rfds, e); Err bitreich.org 70 i 287 if (e == NULL) Err bitreich.org 70 i 288 break; Err bitreich.org 70 i 289 } Err bitreich.org 70 i 290 Err bitreich.org 70 i 291 forllist(wfds, qe) { Err bitreich.org 70 i 292 sendbufi = recvbuf; Err bitreich.org 70 i 293 sendl = recvl; Err bitreich.org 70 i 294 while (sendl > 0) { Err bitreich.org 70 i 295 if ((sent = write(*(int *)qe->data, sendbufi, sendl)) < 0) { Err bitreich.org 70 i 296 close(*(int *)qe->data); Err bitreich.org 70 i 297 qe = llist_del(&wfds, qe); Err bitreich.org 70 i 298 break; Err bitreich.org 70 i 299 } Err bitreich.org 70 i 300 sendl -= sent; Err bitreich.org 70 i 301 sendbufi += sent; Err bitreich.org 70 i 302 } Err bitreich.org 70 i 303 if (qe == NULL) Err bitreich.org 70 i 304 break; Err bitreich.org 70 i 305 } Err bitreich.org 70 i 306 } Err bitreich.org 70 i 307 } Err bitreich.org 70 i 308 Err bitreich.org 70 i 309 } Err bitreich.org 70 i 310 Err bitreich.org 70 i 311 rval = 0; Err bitreich.org 70 i 312 stop_serving: Err bitreich.org 70 i 313 closeallfds(lfds); Err bitreich.org 70 i 314 llist_free(lfds); Err bitreich.org 70 i 315 closeallfds(rfds); Err bitreich.org 70 i 316 llist_free(rfds); Err bitreich.org 70 i 317 closeallfds(wfds); Err bitreich.org 70 i 318 llist_free(wfds); Err bitreich.org 70 i 319 Err bitreich.org 70 i 320 return rval; Err bitreich.org 70 i 321 } Err bitreich.org 70 i 322 Err bitreich.org 70 .