main() { char *x; int udp53; x = env_get("IP"); if (!x) strerr_die2x(111,fatal,"$IP not set"); if (!ip4_scan(x,ip)) strerr_die3x(111,fatal,"unable to parse IP address ",x); udp53 = socket_udp(); if (udp53 == -1) strerr_die2sys(111,fatal,"unable to create UDP socket: "); if (socket_bind4_reuse(udp53,ip,53) == -1) strerr_die2sys(111,fatal,"unable to bind UDP socket: "); droproot(fatal); initialize(); ndelay_off(udp53); socket_tryreservein(udp53,65536); for (;;) { len = socket_recv4(udp53,buf,sizeof buf,ip,&port); if (len < 0) continue; if (!doit()) continue; if (response_len > 512) response_tc(); socket_send4(udp53,response,response_len,ip,port); /* may block for buffer space; if it fails, too bad */ } }
int socket_udp6(void) { #ifdef LIBC_HAS_IP6 int s; if (noipv6) goto compat; s = socket(PF_INET6,SOCK_DGRAM,0); if (s == -1) { if (errno == EINVAL || errno == EAFNOSUPPORT) { compat: s=socket(AF_INET,SOCK_DGRAM,0); noipv6=1; if (s==-1) return -1; } else return -1; } if (ndelay_on(s) == -1) { close(s); return -1; } #ifdef IPV6_V6ONLY { int zero=0; setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,(void*)&zero,sizeof(zero)); } #endif return s; #else return socket_udp(); #endif }
static int udpserver_create(const char* ip, int port) { int ret; socket_t socket; struct sockaddr_in addr; // new a UDP socket socket = socket_udp(); if(socket_error == socket) return 0; // reuse addr socket_setreuseaddr(socket, 1); // bind if(ip && ip[0]) { ret = socket_addr_ipv4(&addr, ip, (unsigned short)port); if(0 == ret) ret = socket_bind(socket, (struct sockaddr*)&addr, sizeof(addr)); } else { ret = socket_bind_any(socket, (unsigned short)port); } if(0 != ret) { socket_close(socket); return 0; } return socket; }
void socket_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { int domain; unsigned int type; int protocol; u_char *pt; PRINT_DEBUG("socket call handler1"); PRINT_DEBUG("%llu", uniqueSockID); pt = buf; domain = *(int *) pt; pt += sizeof(int); type = *(unsigned int *) pt; pt += sizeof(unsigned int); protocol = *(int *) pt; pt += sizeof(int); if (pt - buf != len) { PRINT_DEBUG("READING ERROR! CRASH, diff=%d len=%d", pt - buf, len); nack_send(uniqueSockID, socket_call); return; } PRINT_DEBUG("socket call handler2"); PRINT_DEBUG("%d,%d,%d", domain, protocol, type); if (domain != AF_INET) { PRINT_DEBUG("Wrong domain, only AF_INET us supported"); nack_send(uniqueSockID, socket_call); return; } if (type == SOCK_DGRAM) { socket_udp(domain, type, protocol, uniqueSockID); return; } else if (type == SOCK_STREAM) { socket_tcp(domain, type, protocol, uniqueSockID); return; } else if (type == SOCK_RAW && (protocol == IPPROTO_ICMP)) { socket_icmp(domain, type, protocol, uniqueSockID); return; } else { PRINT_DEBUG("non supported socket type"); return; } return; }
int socket_udp6(void) { #ifdef LIBC_HAS_IP6 int s; if (noipv6) goto compat; s = socket(PF_INET6,SOCK_DGRAM,0); if (s == -1) { if (errno == EINVAL || errno == EAFNOSUPPORT) { compat: s=socket(AF_INET,SOCK_DGRAM,0); noipv6=1; if (s==-1) return -1; } else return -1; } return s; #else return socket_udp(); #endif }
static int thisudp(struct dns_transmit *d) { const char *ip; socketfree(d); while (d->udploop < 4) { for (;d->curserver < 16;++d->curserver) { ip = d->servers + 4 * d->curserver; if (byte_diff(ip,4,"\0\0\0\0")) { d->query[2] = dns_random(256); d->query[3] = dns_random(256); d->s1 = 1 + socket_udp(); if (!d->s1) { dns_transmit_free(d); return -1; } if (randombind(d) == -1) { dns_transmit_free(d); return -1; } if (socket_connect4(d->s1 - 1,ip,53) == 0) if (send(d->s1 - 1,d->query + 2,d->querylen - 2,0) == d->querylen - 2) { struct taia now; taia_now(&now); taia_uint(&d->deadline,timeouts[d->udploop]); taia_add(&d->deadline,&d->deadline,&now); d->tcpstate = 0; return 0; } socketfree(d); } } ++d->udploop; d->curserver = 0; } dns_transmit_free(d); return -1; }
int setup_udp_server_socket(const char ip[4], const char ip6[16], u16 port) { char sip[FMT_IP6]; int fd; fd = socket_udp6(); if(fd >= 0) { if(socket_bind6(fd, ip6, port, 0) == -1) { close(fd); fd = socket_udp(); if(socket_bind4(fd, ip, port) == -1) { ERROR("unable to create server socket: %s", strerror(errno)); } else { fmt_ip4(sip, ip); DEBUG("bound UDP socket on %s:%hu", sip, port); } } else { fmt_ip6(sip, ip6); DEBUG("bound UDP socket on [%s]:%hu", sip, port); } } else { ERROR("unable to create UDP socket: %s", strerror(errno)); } return fd; }
int main (int argc, char *argv[]) { time_t t = 0; char *x = NULL; struct sigaction sa; iopause_fd *iop = NULL; int i = 0, n = 0, *udp53 = NULL; prog = strdup ((x = strrchr (argv[0], '/')) != NULL ? x + 1 : argv[0]); sa.sa_handler = handle_term; sigaction (SIGINT, &sa, NULL); sigaction (SIGTERM, &sa, NULL); sa.sa_handler = SIG_IGN; sigaction (SIGPIPE, &sa, NULL); i = check_option (argc, argv); argc -= i; argv += i; if (mode & DAEMON) { i = fork (); if (i == -1) err (-1, "could not fork a daemon process"); if (i > 0) return 0; } time (&t); memset (buf, 0, sizeof (buf)); strftime (buf, sizeof (buf), "%b-%d %Y %T %Z", localtime (&t)); warnx ("version %s: starting: %s\n", VERSION, buf); set_timezone (); if (debug_level) warnx ("TIMEZONE: %s", env_get ("TZ")); initialize (); if (!debug_level) if ((x = env_get ("DEBUG_LEVEL"))) debug_level = atol (x); warnx ("DEBUG_LEVEL set to `%d'", debug_level); if ((x = env_get ("DATALIMIT"))) { struct rlimit r; unsigned long dlimit = atol (x); if (getrlimit (RLIMIT_DATA, &r) != 0) err (-1, "could not get resource RLIMIT_DATA"); r.rlim_cur = (dlimit <= r.rlim_max) ? dlimit : r.rlim_max; if (setrlimit (RLIMIT_DATA, &r) != 0) err (-1, "could not set resource RLIMIT_DATA"); if (debug_level) warnx ("DATALIMIT set to `%ld' bytes", r.rlim_cur); } if (!(x = env_get ("IP"))) err (-1, "$IP not set"); for (i = 0; (unsigned)i < strlen (x); i++) n = (x[i] == ',') ? n+1 : n; if (!(udp53 = calloc (n+1, sizeof (int)))) err (-1, "could not allocate enough memory for udp53"); if (!(iop = calloc (n+1, sizeof (iopause_fd)))) err (-1, "could not allocate enough memory for iop"); i = n = 0; while (x[i]) { unsigned int l = 0; if (!(l = ip4_scan(x+i, ip))) errx (-1, "could not parse IP address `%s'", x + i); udp53[n] = socket_udp(); if (udp53[n] == -1) errx (-1, "could not open UDP socket"); if (socket_bind4_reuse (udp53[n], ip, server_port) == -1) errx (-1, "could not bind UDP socket"); ndelay_off (udp53[n]); socket_tryreservein (udp53[n], 65536); iop[n].fd = udp53[n]; iop[n].events = IOPAUSE_READ; n++; i += (x[i + l] == ',') ? l + 1 : l; } droproot (); while (1) { struct taia stamp; struct in_addr odst; /* original destination IP */ struct taia deadline; taia_now (&stamp); taia_uint (&deadline, 300); taia_add (&deadline, &deadline, &stamp); iopause (iop, n, &deadline, &stamp); for (i = 0; i < n; i++) { if (!iop[i].revents) continue; len = socket_recv4 (udp53[i], buf, sizeof (buf), ip, &port, &odst); if (len < 0) continue; if (!doit ()) continue; if (response_len > 512) response_tc (); /* may block for buffer space; if it fails, too bad */ len = socket_send4 (udp53[i], response, response_len, ip, port, &odst); if (len < 0) continue; if (debug_level > 1) log_querydone(qnum, response, response_len); } } return 0; }
int main (int argc, char *argv[]) { int i = 0; time_t t = 0; struct sigaction sa; unsigned long cachesize = 0; char *x = NULL, char_seed[128]; sa.sa_handler = handle_term; sigaction (SIGINT, &sa, NULL); sigaction (SIGTERM, &sa, NULL); sa.sa_handler = SIG_IGN; sigaction (SIGPIPE, &sa, NULL); seed_addtime (); seed_adduint32 (getpid ()); seed_adduint32 (getppid ()); seed_adduint32 (getuid ()); seed_adduint32 (getgid ()); seed_addtime (); prog = strdup ((x = strrchr (argv[0], '/')) != NULL ? x + 1 : argv[0]); i = check_option (argc, argv); argc -= i; argv += i; if (mode & DAEMON) { i = fork (); if (i == -1) err (-1, "could not fork a daemon process"); if (i > 0) return 0; } time (&t); strftime (char_seed, sizeof (char_seed), "%b-%d %Y %T %Z", localtime (&t)); warnx ("version %s: starting: %s\n", VERSION, char_seed); set_timezone (); if (debug_level) warnx ("TIMEZONE: %s", env_get ("TZ")); read_conf (CFGFILE); if (!debug_level) if ((x = env_get ("DEBUG_LEVEL"))) debug_level = atol (x); warnx ("DEBUG_LEVEL set to `%d'", debug_level); if ((x = env_get ("DATALIMIT"))) { struct rlimit r; unsigned long dlimit = atol (x); if (getrlimit (RLIMIT_DATA, &r) != 0) err (-1, "could not get resource RLIMIT_DATA"); r.rlim_cur = (dlimit <= r.rlim_max) ? dlimit : r.rlim_max; if (setrlimit (RLIMIT_DATA, &r) != 0) err (-1, "could not set resource RLIMIT_DATA"); if (debug_level) warnx ("DATALIMIT set to `%ld' bytes", r.rlim_cur); } if (!(x = env_get ("IP"))) err (-1, "$IP not set"); if (!ip4_scan (x, myipincoming)) err (-1, "could not parse IP address `%s'", x); seed_addtime (); udp53 = socket_udp (); if (udp53 == -1) err (-1, "could not open UDP socket"); if (socket_bind4_reuse (udp53, myipincoming, 53) == -1) err (-1, "could not bind UDP socket"); seed_addtime (); tcp53 = socket_tcp (); if (tcp53 == -1) err (-1, "could not open TCP socket"); if (socket_bind4_reuse (tcp53, myipincoming, 53) == -1) err (-1, "could not bind TCP socket"); if (mode & DAEMON) { /* redirect stdout & stderr to a log file */ redirect_to_log (LOGFILE, STDOUT_FILENO | STDERR_FILENO); write_pid (PIDFILE); } seed_addtime (); droproot (); if (mode & DAEMON) /* crerate a new session & detach from controlling tty */ if (setsid () < 0) err (-1, "could not start a new session for the daemon"); seed_addtime (); socket_tryreservein (udp53, 131072); memset (char_seed, 0, sizeof (char_seed)); for (i = 0, x = (char *)seed; (unsigned)i < sizeof (char_seed); i++, x++) char_seed[i] = *x; dns_random_init (char_seed); if (!(x = env_get ("IPSEND"))) err (-1, "$IPSEND not set"); if (!ip4_scan (x, myipoutgoing)) err (-1, "could not parse IP address `%s'", x); if (!(x = env_get ("CACHESIZE"))) err (-1, "$CACHESIZE not set"); scan_ulong (x, &cachesize); if (!cache_init (cachesize)) err (-1, "could not allocate `%ld' bytes for cache", cachesize); if (env_get ("HIDETTL")) response_hidettl (); if (env_get ("FORWARDONLY")) query_forwardonly (); if (env_get ("MERGEQUERIES")) dns_enable_merge (log_merge); if (!roots_init ()) err (-1, "could not read servers"); if (debug_level > 3) roots_display(); if (socket_listen (tcp53, 20) == -1) err (-1, "could not listen on TCP socket"); if (!dbl_init() && debug_level > 1) warnx ("could not read dnsbl.cdb"); doit (); return 0; }
static int thisudp (struct dns_transmit *d) { const char *ip = NULL; socketfree (d); mergefree (d); while (d->udploop < 4) { for (; d->curserver < 16; ++d->curserver) { ip = d->servers + 4 * d->curserver; if (byte_diff (ip, 4, "\0\0\0\0")) { if (merge_enable && try_merge (d)) { if (merge_logger) merge_logger (ip, d->qtype, d->query + 14); return 0; } d->query[2] = dns_random (256); d->query[3] = dns_random (256); d->s1 = 1 + socket_udp (); if (!d->s1) { dns_transmit_free (d); return -1; } if (randombind (d) == -1) { dns_transmit_free (d); return -1; } if (socket_connect4 (d->s1 - 1, ip, 53) == 0) { if (send (d->s1 - 1, d->query + 2, d->querylen - 2, 0) == d->querylen - 2) { struct taia now; taia_now (&now); taia_uint (&d->deadline, timeouts[d->udploop]); taia_add (&d->deadline, &d->deadline, &now); d->tcpstate = 0; if (merge_enable) register_inprogress (d); return 0; } } socketfree (d); } } ++d->udploop; d->curserver = 0; } dns_transmit_free (d); return -1; }
int cli_main(int argc, char* argv[]) { const char* server_name = 0; const char* env; msg_debug_init(); encr_start(); prep_sender(); service = argv[0]; if (argc > 1 && argv[1][0] != '-' && argv[1][0] != '+') { server_name = argv[1]; ++argv; --argc; } if (argc > 1) load_patterns(argv + 1); if (server_name == 0 && (server_name = getenv("SERVER")) == 0) die1(1, "Server address not named on command line nor in $SERVER"); if (!resolve_ipv4name(server_name, &ip)) die3(1, "Could not resolve '", server_name, "'"); brandom_init(); if ((env = getenv("KEYDIR")) != 0) keydir = env; load_keys(server_name); if ((env = getenv("PORT")) != 0) port = strtoul(env, 0, 10); if (port == 0) port = 11014; if ((sock = socket_udp()) == -1) die1sys(1, "Could not create UDP socket"); if (!socket_connect4(sock, &ip, port)) die1sys(1, "Could not bind socket"); if (!str_ready(&packet, 65535) || !str_ready(&rpacket, 4+4+8+256*5)) die1(1, "Out of memory"); getenvu("ACK_TIMEOUT", &ack_timeout); getenvu("CID_TIMEOUT", &cid_timeout); getenvu("RETRANSMITS", &retransmits); getenvu("READWAIT", &readwait); getenvu("STARTLINES", &startlines); if (getenv("EXITONEOF") != 0) exitoneof = 1; if (getenv("NOFILES") == 0 && getenv("NOFILE") == 0) buffer = buffer_file_init(); else buffer = buffer_nofile_init(); sig_all_catch(sigfn); exitasap = 0; mainloop(); return 0; }
int main(int argc,char **argv) { long long hellopackets; long long r; long long nextaction; signal(SIGPIPE,SIG_IGN); if (!argv[0]) die_usage(0); for (;;) { char *x; if (!argv[1]) break; if (argv[1][0] != '-') break; x = *++argv; if (x[0] == '-' && x[1] == 0) break; if (x[0] == '-' && x[1] == '-' && x[2] == 0) break; while (*++x) { if (*x == 'q') { flagverbose = 0; continue; } if (*x == 'Q') { flagverbose = 1; continue; } if (*x == 'v') { if (flagverbose == 2) flagverbose = 3; else flagverbose = 2; continue; } if (*x == 'c') { if (x[1]) { keydir = x + 1; break; } if (argv[1]) { keydir = *++argv; break; } } die_usage(0); } } if (!nameparse(servername,*++argv)) die_usage("sname must be at most 255 bytes, at most 63 bytes between dots"); if (!hexparse(serverlongtermpk,32,*++argv)) die_usage("pk must be exactly 64 hex characters"); if (!multiipparse(serverip,*++argv)) die_usage("ip must be a comma-separated series of IPv4 addresses"); if (!portparse(serverport,*++argv)) die_usage("port must be an integer between 0 and 65535"); if (!hexparse(serverextension,16,*++argv)) die_usage("ext must be exactly 32 hex characters"); if (!*++argv) die_usage("missing prog"); for (;;) { r = open_read("/dev/null"); if (r == -1) die_fatal("unable to open /dev/null",0,0); if (r > 9) { close(r); break; } } if (keydir) { fdwd = open_cwd(); if (fdwd == -1) die_fatal("unable to open current working directory",0,0); if (chdir(keydir) == -1) die_fatal("unable to change to directory",keydir,0); if (load("publickey",clientlongtermpk,sizeof clientlongtermpk) == -1) die_fatal("unable to read public key from",keydir,0); if (load(".expertsonly/secretkey",clientlongtermsk,sizeof clientlongtermsk) == -1) die_fatal("unable to read secret key from",keydir,0); } else { crypto_box_keypair(clientlongtermpk,clientlongtermsk); } crypto_box_keypair(clientshorttermpk,clientshorttermsk); clientshorttermnonce = randommod(281474976710656LL); crypto_box_beforenm(clientshortserverlong,serverlongtermpk,clientshorttermsk); crypto_box_beforenm(clientlongserverlong,serverlongtermpk,clientlongtermsk); udpfd = socket_udp(); if (udpfd == -1) die_fatal("unable to create socket",0,0); for (hellopackets = 0;hellopackets < NUMIP;++hellopackets) { recent = nanoseconds(); /* send a Hello packet: */ clientextension_init(); clientshorttermnonce_update(); byte_copy(nonce,16,"CurveCP-client-H"); uint64_pack(nonce + 16,clientshorttermnonce); byte_copy(packet,8,"QvnQ5XlH"); byte_copy(packet + 8,16,serverextension); byte_copy(packet + 24,16,clientextension); byte_copy(packet + 40,32,clientshorttermpk); byte_copy(packet + 72,64,allzero); byte_copy(packet + 136,8,nonce + 16); crypto_box_afternm(text,allzero,96,nonce,clientshortserverlong); byte_copy(packet + 144,80,text + 16); socket_send(udpfd,packet,224,serverip + 4 * hellopackets,serverport); nextaction = recent + hellowait[hellopackets] + randommod(hellowait[hellopackets]); for (;;) { long long timeout = nextaction - recent; if (timeout <= 0) break; p[0].fd = udpfd; p[0].events = POLLIN; if (poll(p,1,timeout / 1000000 + 1) < 0) p[0].revents = 0; do { /* try receiving a Cookie packet: */ if (!p[0].revents) break; r = socket_recv(udpfd,packet,sizeof packet,packetip,packetport); if (r != 200) break; if (!(byte_isequal(packetip,4,serverip + 4 * hellopackets) & byte_isequal(packetport,2,serverport) & byte_isequal(packet,8,"RL3aNMXK") & byte_isequal(packet + 8,16,clientextension) & byte_isequal(packet + 24,16,serverextension) )) break; byte_copy(nonce,8,"CurveCPK"); byte_copy(nonce + 8,16,packet + 40); byte_zero(text,16); byte_copy(text + 16,144,packet + 56); if (crypto_box_open_afternm(text,text,160,nonce,clientshortserverlong)) break; byte_copy(servershorttermpk,32,text + 32); byte_copy(servercookie,96,text + 64); byte_copy(serverip,4,serverip + 4 * hellopackets); goto receivedcookie; } while (0); recent = nanoseconds(); } } errno = ETIMEDOUT; die_fatal("no response from server",0,0); receivedcookie: crypto_box_beforenm(clientshortservershort,servershorttermpk,clientshorttermsk); byte_copy(nonce,8,"CurveCPV"); if (keydir) { if (safenonce(nonce + 8,0) == -1) die_fatal("nonce-generation disaster",0,0); } else { randombytes(nonce + 8,16); } byte_zero(text,32); byte_copy(text + 32,32,clientshorttermpk); crypto_box_afternm(text,text,64,nonce,clientlongserverlong); byte_copy(vouch,16,nonce + 8); byte_copy(vouch + 16,48,text + 16); /* server is responding, so start child: */ if (open_pipe(tochild) == -1) die_fatal("unable to create pipe",0,0); if (open_pipe(fromchild) == -1) die_fatal("unable to create pipe",0,0); child = fork(); if (child == -1) die_fatal("unable to fork",0,0); if (child == 0) { if (keydir) if (fchdir(fdwd) == -1) die_fatal("unable to chdir to original directory",0,0); close(8); if (dup(tochild[0]) != 8) die_fatal("unable to dup",0,0); close(9); if (dup(fromchild[1]) != 9) die_fatal("unable to dup",0,0); /* XXX: set up environment variables */ signal(SIGPIPE,SIG_DFL); execvp(*argv,argv); die_fatal("unable to run",*argv,0); } close(fromchild[1]); close(tochild[0]); for (;;) { p[0].fd = udpfd; p[0].events = POLLIN; p[1].fd = fromchild[0]; p[1].events = POLLIN; if (poll(p,2,-1) < 0) { p[0].revents = 0; p[1].revents = 0; } do { /* try receiving a Message packet: */ if (!p[0].revents) break; r = socket_recv(udpfd,packet,sizeof packet,packetip,packetport); if (r < 80) break; if (r > 1152) break; if (r & 15) break; packetnonce = uint64_unpack(packet + 40); if (flagreceivedmessage && packetnonce <= receivednonce) break; if (!(byte_isequal(packetip,4,serverip + 4 * hellopackets) & byte_isequal(packetport,2,serverport) & byte_isequal(packet,8,"RL3aNMXM") & byte_isequal(packet + 8,16,clientextension) & byte_isequal(packet + 24,16,serverextension) )) break; byte_copy(nonce,16,"CurveCP-server-M"); byte_copy(nonce + 16,8,packet + 40); byte_zero(text,16); byte_copy(text + 16,r - 48,packet + 48); if (crypto_box_open_afternm(text,text,r - 32,nonce,clientshortservershort)) break; if (!flagreceivedmessage) { flagreceivedmessage = 1; randombytes(clientlongtermpk,sizeof clientlongtermpk); randombytes(vouch,sizeof vouch); randombytes(servername,sizeof servername); randombytes(servercookie,sizeof servercookie); } receivednonce = packetnonce; text[31] = (r - 64) >> 4; /* child is responsible for reading all data immediately, so we won't block: */ if (writeall(tochild[1],text + 31,r - 63) == -1) goto done; } while (0); do { /* try receiving data from child: */ long long i; if (!p[1].revents) break; r = read(fromchild[0],childbuf,sizeof childbuf); if (r == -1) if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) break; if (r <= 0) goto done; childbuflen = r; for (i = 0;i < childbuflen;++i) { if (childmessagelen < 0) goto done; if (childmessagelen >= sizeof childmessage) goto done; childmessage[childmessagelen++] = childbuf[i]; if (childmessage[0] & 128) goto done; if (childmessagelen == 1 + 16 * (unsigned long long) childmessage[0]) { clientextension_init(); clientshorttermnonce_update(); uint64_pack(nonce + 16,clientshorttermnonce); if (flagreceivedmessage) { r = childmessagelen - 1; if (r < 16) goto done; if (r > 1088) goto done; byte_copy(nonce,16,"CurveCP-client-M"); byte_zero(text,32); byte_copy(text + 32,r,childmessage + 1); crypto_box_afternm(text,text,r + 32,nonce,clientshortservershort); byte_copy(packet,8,"QvnQ5XlM"); byte_copy(packet + 8,16,serverextension); byte_copy(packet + 24,16,clientextension); byte_copy(packet + 40,32,clientshorttermpk); byte_copy(packet + 72,8,nonce + 16); byte_copy(packet + 80,r + 16,text + 16); socket_send(udpfd,packet,r + 96,serverip,serverport); } else { r = childmessagelen - 1; if (r < 16) goto done; if (r > 640) goto done; byte_copy(nonce,16,"CurveCP-client-I"); byte_zero(text,32); byte_copy(text + 32,32,clientlongtermpk); byte_copy(text + 64,64,vouch); byte_copy(text + 128,256,servername); byte_copy(text + 384,r,childmessage + 1); crypto_box_afternm(text,text,r + 384,nonce,clientshortservershort); byte_copy(packet,8,"QvnQ5XlI"); byte_copy(packet + 8,16,serverextension); byte_copy(packet + 24,16,clientextension); byte_copy(packet + 40,32,clientshorttermpk); byte_copy(packet + 72,96,servercookie); byte_copy(packet + 168,8,nonce + 16); byte_copy(packet + 176,r + 368,text + 16); socket_send(udpfd,packet,r + 544,serverip,serverport); } childmessagelen = 0; } } } while (0); } done: do { r = waitpid(child,&childstatus,0); } while (r == -1 && errno == EINTR); if (!WIFEXITED(childstatus)) { errno = 0; die_fatal("process killed by signal",0,0); } return WEXITSTATUS(childstatus); }