int socket_remote6(int s,char ip[16],uint16 *port,uint32 *scope_id) { #ifdef LIBC_HAS_IP6 struct sockaddr_in6 si; #else struct sockaddr_in si; #endif socklen_t len = sizeof si; if (getpeername(s,(struct sockaddr *) &si,&len) == -1) return -1; #ifdef LIBC_HAS_IP6 if (si.sin6_family==AF_INET) { struct sockaddr_in *si4=(struct sockaddr_in*)&si; byte_copy(ip,12,V4mappedprefix); byte_copy(ip+12,4,(char *) &si4->sin_addr); uint16_unpack_big((char *) &si4->sin_port,port); return 0; } byte_copy(ip,16,(char *) &si.sin6_addr); uint16_unpack_big((char *) &si.sin6_port,port); if (scope_id) *scope_id=si.sin6_scope_id; #else byte_copy(ip,12,V4mappedprefix); byte_copy(ip+12,4,(char *) &si.sin_addr); uint16_unpack_big((char *) &si.sin_port,port); if (scope_id) *scope_id=0; #endif return 0; }
void s6dns_message_counts_unpack (char const *s, s6dns_message_counts_t *counts) { uint16_unpack_big(s, &counts->qd) ; uint16_unpack_big(s+2, &counts->an) ; uint16_unpack_big(s+4, &counts->ns) ; uint16_unpack_big(s+6, &counts->nr) ; }
int socket_accept6(int s,char ip[16],uint16 *port,uint32 *scope_id) { #ifdef LIBC_HAS_IP6 struct sockaddr_in6 sa; #else struct sockaddr_in sa; #endif unsigned int dummy = sizeof sa; int fd; fd = accept(s,(struct sockaddr *) &sa,&dummy); if (fd == -1) return -1; #ifdef LIBC_HAS_IP6 if (sa.sin6_family==AF_INET) { struct sockaddr_in *sa4=(struct sockaddr_in*)&sa; byte_copy(ip,12,V4mappedprefix); byte_copy(ip+12,4,(char *) &sa4->sin_addr); uint16_unpack_big((char *) &sa4->sin_port,port); return fd; } byte_copy(ip,16,(char *) &sa.sin6_addr); uint16_unpack_big((char *) &sa.sin6_port,port); if (scope_id) *scope_id=sa.sin6_scope_id; return fd; #else byte_copy(ip,12,V4mappedprefix); byte_copy(ip+12,4,(char *) &sa.sin_addr); uint16_unpack_big((char *) &sa.sin_port,port); if (scope_id) *scope_id=0; return fd; #endif }
int dns_mx_packet(stralloc *out,const char *buf,unsigned int len) { unsigned int pos; char header[12]; char pref[2]; uint16 numanswers; uint16 datalen; if (!stralloc_copys(out,"")) return -1; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; uint16_unpack_big(header + 6,&numanswers); pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos += 4; while (numanswers--) { pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; uint16_unpack_big(header + 8,&datalen); if (byte_equal(header,2,DNS_T_MX)) if (byte_equal(header + 2,2,DNS_C_IN)) { if (!dns_packet_copy(buf,len,pos,pref,2)) return -1; if (!dns_packet_getname(buf,len,pos + 2,&q)) return -1; if (!stralloc_catb(out,pref,2)) return -1; if (!dns_domain_todot_cat(out,q)) return -1; if (!stralloc_0(out)) return -1; } pos += datalen; } return 0; }
int dns_ip4_packet(stralloc *out,const char *buf,unsigned int len) { unsigned int pos; char header[12]; uint16 numanswers; uint16 datalen; if (!stralloc_copys(out,"")) return -1; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; uint16_unpack_big(header + 6,&numanswers); pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos += 4; while (numanswers--) { pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; uint16_unpack_big(header + 8,&datalen); if (byte_equal(header,2,DNS_T_A)) if (byte_equal(header + 2,2,DNS_C_IN)) if (datalen == 4) { if (!dns_packet_copy(buf,len,pos,header,4)) return -1; if (!stralloc_catb(out,header,4)) return -1; } pos += datalen; } dns_sortip(out->s,out->len); return 0; }
int socket_recv6(int s,char *buf,unsigned int len,char ip[16],uint16 *port,uint32 *scope_id) { #ifdef LIBC_HAS_IP6 struct sockaddr_in6 sa; #else struct sockaddr_in sa; #endif unsigned int dummy = sizeof sa; int r; byte_zero(&sa,dummy); r = recvfrom(s,buf,len,0,(struct sockaddr *) &sa,&dummy); if (r == -1) return -1; #ifdef LIBC_HAS_IP6 if (noipv6) { struct sockaddr_in *sa4=(struct sockaddr_in *)&sa; byte_copy(ip,12,V4mappedprefix); byte_copy(ip+12,4,(char *) &sa4->sin_addr); uint16_unpack_big((char *) &sa4->sin_port,port); return r; } byte_copy(ip,16,(char *) &sa.sin6_addr); uint16_unpack_big((char *) &sa.sin6_port,port); if (scope_id) *scope_id=sa.sin6_scope_id; #else byte_copy(ip,12,(char *)V4mappedprefix); byte_copy(ip+12,4,(char *) &sa.sin_addr); uint16_unpack_big((char *) &sa.sin_port,port); if (scope_id) *scope_id=0; #endif return r; }
int s6dns_message_parse_getrr (s6dns_message_rr_t_ref rr, char const *packet, unsigned int packetlen, unsigned int *pos) { if (!s6dns_message_get_domain(&rr->name, packet, packetlen, pos)) return 0 ; if (*pos + 10 > packetlen) return (errno = EPROTO, 0) ; uint16_unpack_big(packet + *pos, &rr->rtype) ; *pos += 2 ; uint16_unpack_big(packet + *pos, &rr->rclass) ; *pos += 2 ; uint32_unpack_big(packet + *pos, &rr->ttl) ; *pos += 4 ; uint16_unpack_big(packet + *pos, &rr->rdlength) ; *pos += 2 ; if (*pos + rr->rdlength > packetlen) return (errno = EPROTO, 0) ; return 1 ; }
int printtype(stralloc *out, const char type[2]) { uint16 u16; if (byte_equal(type,2,DNS_T_A)) return stralloc_cats(out,"A"); if (byte_equal(type,2,DNS_T_NS)) return stralloc_cats(out,"NS"); if (byte_equal(type,2,DNS_T_CNAME)) return stralloc_cats(out,"CNAME"); if (byte_equal(type,2,DNS_T_SOA)) return stralloc_cats(out,"SOA"); if (byte_equal(type,2,DNS_T_PTR)) return stralloc_cats(out,"PTR"); if (byte_equal(type,2,DNS_T_HINFO)) return stralloc_cats(out,"HINFO"); if (byte_equal(type,2,DNS_T_MX)) return stralloc_cats(out,"MX"); if (byte_equal(type,2,DNS_T_TXT)) return stralloc_cats(out,"TXT"); if (byte_equal(type,2,DNS_T_RP)) return stralloc_cats(out,"RP"); if (byte_equal(type,2,DNS_T_SIG)) return stralloc_cats(out,"SIG"); if (byte_equal(type,2,DNS_T_KEY)) return stralloc_cats(out,"KEY"); if (byte_equal(type,2,DNS_T_AAAA)) return stralloc_cats(out,"AAAA"); if (byte_equal(type,2,DNS_T_OPT)) return stralloc_cats(out,"OPT"); if (byte_equal(type,2,DNS_T_DS)) return stralloc_cats(out,"DS"); if (byte_equal(type,2,DNS_T_RRSIG)) return stralloc_cats(out,"RRSIG"); if (byte_equal(type,2,DNS_T_DNSKEY)) return stralloc_cats(out,"DNSKEY"); if (byte_equal(type,2,DNS_T_NSEC3)) return stralloc_cats(out,"NSEC3"); if (byte_equal(type,2,DNS_T_NSEC3PARAM)) return stralloc_cats(out,"NSEC3PARAM"); if (byte_equal(type,2,DNS_T_AXFR)) return stralloc_cats(out,"AXFR"); if (byte_equal(type,2,DNS_T_ANY)) return stralloc_cats(out,"*"); uint16_unpack_big(type,&u16); return stralloc_catulong0(out,u16,0); }
int socket_recv4(int s,char *buf,unsigned int len,char ip[4],uint16 *port) { struct sockaddr_in si; socklen_t Len = sizeof si; int r; if ((r = recvfrom(s,buf,len,0,(struct sockaddr *) &si,&Len))<0) return -1; *(uint32*)ip = *(uint32*)&si.sin_addr; uint16_unpack_big((char *) &si.sin_port,port); return r; }
ssize_t socket_recv4(int s,char *buf,size_t len,char ip[4],uint16 *port) { struct sockaddr_in si; socklen_t Len = sizeof si; ssize_t r; if ((r = recvfrom(s,buf,len,0,(struct sockaddr *) &si,&Len))<0) return winsock2errno(-1); if (ip) *(uint32*)ip = *(uint32*)&si.sin_addr; if (port) uint16_unpack_big((char *) &si.sin_port,port); return r; }
int socket_local4(int s,char ip[4],uint16 *port) { struct sockaddr_in sa; socklen_t dummy = sizeof sa; if (getsockname(s,(struct sockaddr *) &sa,&dummy) == -1) return -1; byte_copy(ip,4,(char *) &sa.sin_addr); uint16_unpack_big((char *) &sa.sin_port,port); return 0; }
int dns_txt_packet(stralloc *out,const char *buf,unsigned int len) { unsigned int pos; char header[12]; uint16 numanswers; uint16 datalen; char ch; unsigned int txtlen; int i; if (!stralloc_copys(out,"")) return -1; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; uint16_unpack_big(header + 6,&numanswers); pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos += 4; while (numanswers--) { pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; uint16_unpack_big(header + 8,&datalen); if (byte_equal(header,2,DNS_T_TXT)) if (byte_equal(header + 2,2,DNS_C_IN)) { if (pos + datalen > len) return -1; txtlen = 0; for (i = 0;i < datalen;++i) { ch = buf[pos + i]; if (!txtlen) txtlen = (unsigned char) ch; else { --txtlen; if (ch < 32) ch = '?'; if (ch > 126) ch = '?'; if (!stralloc_append(out,&ch)) return -1; } } } pos += datalen; } return 0; }
ssize_t socket_recv6(int s,char *buf,size_t len,char ip[16],uint16 *port,uint32 *scope_id) { #ifdef LIBC_HAS_IP6 struct sockaddr_in6 si; #else struct sockaddr_in si; #endif socklen_t Len = sizeof si; ssize_t r; byte_zero(&si,Len); if ((r = recvfrom(s,buf,len,0,(struct sockaddr *) &si,&Len))<0) return winsock2errno(-1); #ifdef LIBC_HAS_IP6 if (noipv6 || si.sin6_family==AF_INET || si.sin6_family==PF_INET) { struct sockaddr_in *si4=(struct sockaddr_in *)&si; if (ip) { byte_copy(ip,12,V4mappedprefix); byte_copy(ip+12,4,(char *) &si4->sin_addr); } if (port) uint16_unpack_big((char *) &si4->sin_port,port); return r; } if (ip) byte_copy(ip,16,(char *) &si.sin6_addr); if (port) uint16_unpack_big((char *) &si.sin6_port,port); #ifdef LIBC_HAS_SCOPE_ID if (scope_id) *scope_id=si.sin6_scope_id; #else if (scope_id) *scope_id=0; #endif #else if (ip) { byte_copy(ip,12,(char *)V4mappedprefix); byte_copy(ip+12,4,(char *) &si.sin_addr); } if (port) uint16_unpack_big((char *) &si.sin_port,port); if (scope_id) *scope_id=0; #endif return r; }
int socket_recv4 (int s, char *buf, unsigned int len, char *ip, uint16 *port) { struct sockaddr_in sa ; socklen_t dummy = sizeof sa ; register int r ; do r = recvfrom(s, buf, len, 0, (struct sockaddr *)&sa, &dummy) ; while ((r == -1) && (errno == EINTR)) ; if (r == -1) return -1 ; byte_copy(ip, 4, (char *)&sa.sin_addr) ; uint16_unpack_big((char *)&sa.sin_port, port) ; return r ; }
int socket_remote46 (int s, ip46_t *ip, uint16 *port) { struct sockaddr sa ; socklen_t dummy = sizeof sa ; if (getpeername(s, &sa, &dummy) < 0) return -1 ; if (sa.sa_family == AF_INET6) { register struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&sa ; byte_copy(ip->ip, 16, (char const *)sa6->sin6_addr.s6_addr) ; uint16_unpack_big((char *)&sa6->sin6_port, port) ; ip->is6 = 1 ; } else if (sa.sa_family == AF_INET) { register struct sockaddr_in *sa4 = (struct sockaddr_in *)&sa ; byte_copy(ip->ip, 4, (char const *)&sa4->sin_addr.s_addr) ; uint16_unpack_big((char *)&sa4->sin_port, port) ; ip->is6 = 0 ; } else return (errno = EAFNOSUPPORT, -1) ; return 0 ; }
int socket_local6(int s,char ip[16],uint16 *port,uint32 *scope_id) { #ifdef LIBC_HAS_IP6 struct sockaddr_in6 si; #else struct sockaddr_in si; #endif socklen_t len = sizeof si; if (getsockname(s,(void*) &si,&len) == -1) return winsock2errno(-1); #ifdef LIBC_HAS_IP6 if (si.sin6_family==AF_INET) { struct sockaddr_in *si4=(void*)&si; if (ip) { byte_copy(ip,12,V4mappedprefix); byte_copy(ip+12,4,(char *) &si4->sin_addr); } if (port) uint16_unpack_big((char *) &si4->sin_port,port); return 0; } if (ip) byte_copy(ip,16,(char *) &si.sin6_addr); if (port) uint16_unpack_big((char *) &si.sin6_port,port); #ifdef LIBC_HAS_SCOPE_ID if (scope_id) *scope_id=si.sin6_scope_id; #else if (scope_id) *scope_id=0; #endif #else if (ip) { byte_copy(ip,12,V4mappedprefix); byte_copy(ip+12,4,(char *) &si.sin_addr); } if (port) uint16_unpack_big((char *) &si.sin_port,port); if (scope_id) *scope_id=0; #endif return 0; }
int socket_recv4(int s,char *buf,int len,char ip[4],uint16 *port) { struct sockaddr_in sa; int dummy = sizeof sa; int r; r = recvfrom(s,buf,len,0,(struct sockaddr *) &sa,&dummy); if (r == -1) return -1; byte_copy(ip,4,(char *) &sa.sin_addr); uint16_unpack_big((char *) &sa.sin_port,port); return r; }
int socket_accept4(int s,char ip[4],uint16 *port) { struct sockaddr_in sa; int dummy = sizeof sa; int fd; fd = accept(s,(struct sockaddr *) &sa,&dummy); if (fd == -1) return -1; byte_copy(ip,4,(char *) &sa.sin_addr); uint16_unpack_big((char *) &sa.sin_port,port); return fd; }
void s6_svstatus_unpack (char const *pack, s6_svstatus_t *sv) { uint64 pid ; uint16 wstat ; tain_unpack(pack, &sv->stamp) ; tain_unpack(pack + 12, &sv->readystamp) ; uint64_unpack_big(pack + 24, &pid) ; sv->pid = (pid_t)pid ; uint16_unpack_big(pack + 32, &wstat) ; sv->wstat = (int)wstat ; sv->flagpaused = pack[34] & 1 ; sv->flagfinishing = !!(pack[34] & 2) ; sv->flagwant = !!(pack[34] & 4) ; sv->flagwantup = !!(pack[34] & 8) ; sv->flagready = !!(pack[34] & 16) ; }
int socket_recv4(int s,char *buf,int len,char ip[4],uint16 *port,char dstip[4]) { struct sockaddr_in sa; int dummy = sizeof sa; int r; if (dstip == NULL) { r = recvfrom(s,buf,len,0,(struct sockaddr *) &sa,&dummy); if (r == -1) return -1; } else { struct iovec iov; struct cmsghdr cmsg, *cmsgptr; struct msghdr msg; char cbuf[64]; byte_zero(&cmsg, sizeof(cmsg)); byte_zero(&msg, sizeof(msg)); iov.iov_base = buf; iov.iov_len = len; msg.msg_name = &sa; msg.msg_namelen = dummy; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = cbuf; msg.msg_controllen = sizeof(cbuf); r = recvmsg(s, &msg, 0); if (r == -1) return (-1); for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { if (cmsgptr->cmsg_level == SOL_IP && cmsgptr->cmsg_type == IP_PKTINFO) { struct in_pktinfo *pki = (struct in_pktinfo *)CMSG_DATA(cmsgptr); byte_copy(dstip, 4, (char *)&(pki->ipi_addr)); } } } byte_copy(ip,4,(char *) &sa.sin_addr); uint16_unpack_big((char *) &sa.sin_port,port); return r; }
static int want(const char *owner,const char type[2]) { unsigned int pos; static char *d; char x[10]; uint16 datalen; pos = dns_packet_skipname(response,response_len,12); if (!pos) return 0; pos += 4; while (pos < response_len) { pos = dns_packet_getname(response,response_len,pos,&d); if (!pos) return 0; pos = dns_packet_copy(response,response_len,pos,x,10); if (!pos) return 0; if (dns_domain_equal(d,owner)) if (byte_equal(type,2,x)) return 0; uint16_unpack_big(x + 8,&datalen); pos += datalen; } return 1; }
int main(int argc,char **argv) { uint16 u16; dns_random_init(seed); if (!*argv) usage(); if (!*++argv) usage(); if (!parsetype(*argv,type)) usage(); if (!*++argv) usage(); if (!dns_domain_fromdot(&q,*argv,str_len(*argv))) oops(); if (!*++argv) usage(); if (!stralloc_copys(&out,*argv)) oops(); if (dns_ip6_qualify(&ip,&fqdn,&out) == -1) oops(); if (ip.len >= 256) ip.len = 256; byte_zero(servers,256); byte_copy(servers,ip.len,ip.s); if (!stralloc_copys(&out,"")) oops(); uint16_unpack_big(type,&u16); if (!stralloc_catulong0(&out,u16,0)) oops(); if (!stralloc_cats(&out," ")) oops(); if (!dns_domain_todot_cat(&out,q)) oops(); if (!stralloc_cats(&out,":\n")) oops(); if (resolve(q,type,servers) == -1) { if (!stralloc_cats(&out,error_str(errno))) oops(); if (!stralloc_cats(&out,"\n")) oops(); } else { if (!printpacket_cat(&out,tx.packet,tx.packetlen)) oops(); } buffer_putflush(buffer_1,out.s,out.len); _exit(0); }
static int doit(char *q,char qtype[2]) { unsigned int bpos; unsigned int anpos; unsigned int aupos; unsigned int arpos; char *control; char *wild; int flaggavesoa; int flagfound; int r; int flagns; int flagauthoritative; char x[20]; uint16 u16; char addr[8][4]; int addrnum; uint32 addrttl; int i; anpos = response_len; control = q; for (;;) { flagns = 0; flagauthoritative = 0; cdb_findstart(&c); while (r = find(control,0)) { if (r == -1) return 0; if (byte_equal(type,2,DNS_T_SOA)) flagauthoritative = 1; if (byte_equal(type,2,DNS_T_NS)) flagns = 1; } if (flagns) break; if (!*control) return 0; /* q is not within our bailiwick */ control += *control; control += 1; } if (!flagauthoritative) { response[2] &= ~4; goto AUTHORITY; /* q is in a child zone */ } flaggavesoa = 0; flagfound = 0; wild = q; for (;;) { addrnum = 0; addrttl = 0; cdb_findstart(&c); while (r = find(wild,wild != q)) { if (r == -1) return 0; flagfound = 1; if (flaggavesoa && byte_equal(type,2,DNS_T_SOA)) continue; if (byte_diff(type,2,qtype) && byte_diff(qtype,2,DNS_T_ANY) && byte_diff(type,2,DNS_T_CNAME)) continue; if (byte_equal(type,2,DNS_T_A) && (dlen - dpos == 4)) { addrttl = ttl; i = dns_random(addrnum + 1); if (i < 8) { if ((i < addrnum) && (addrnum < 8)) byte_copy(addr[addrnum],4,addr[i]); byte_copy(addr[i],4,data + dpos); } if (addrnum < 1000000) ++addrnum; continue; } if (!response_rstart(q,type,ttl)) return 0; if (byte_equal(type,2,DNS_T_NS) || byte_equal(type,2,DNS_T_CNAME) || byte_equal(type,2,DNS_T_PTR)) { if (!doname()) return 0; } else if (byte_equal(type,2,DNS_T_MX)) { if (!dobytes(2)) return 0; if (!doname()) return 0; } else if (byte_equal(type,2,DNS_T_SOA)) { if (!doname()) return 0; if (!doname()) return 0; if (!dobytes(20)) return 0; flaggavesoa = 1; } else if (!response_addbytes(data + dpos,dlen - dpos)) return 0; response_rfinish(RESPONSE_ANSWER); } for (i = 0;i < addrnum;++i) if (i < 8) { if (!response_rstart(q,DNS_T_A,addrttl)) return 0; if (!response_addbytes(addr[i],4)) return 0; response_rfinish(RESPONSE_ANSWER); } if (flagfound) break; if (wild == control) break; if (!*wild) break; /* impossible */ wild += *wild; wild += 1; } if (!flagfound) response_nxdomain(); AUTHORITY: aupos = response_len; if (flagauthoritative && (aupos == anpos)) { cdb_findstart(&c); while (r = find(control,0)) { if (r == -1) return 0; if (byte_equal(type,2,DNS_T_SOA)) { if (!response_rstart(control,DNS_T_SOA,ttl)) return 0; if (!doname()) return 0; if (!doname()) return 0; if (!dobytes(20)) return 0; response_rfinish(RESPONSE_AUTHORITY); break; } } } else if (want(control,DNS_T_NS)) { cdb_findstart(&c); while (r = find(control,0)) { if (r == -1) return 0; if (byte_equal(type,2,DNS_T_NS)) { if (!response_rstart(control,DNS_T_NS,ttl)) return 0; if (!doname()) return 0; response_rfinish(RESPONSE_AUTHORITY); } } } arpos = response_len; bpos = anpos; while (bpos < arpos) { bpos = dns_packet_skipname(response,arpos,bpos); if (!bpos) return 0; bpos = dns_packet_copy(response,arpos,bpos,x,10); if (!bpos) return 0; if (byte_equal(x,2,DNS_T_NS) || byte_equal(x,2,DNS_T_MX)) { if (byte_equal(x,2,DNS_T_NS)) { if (!dns_packet_getname(response,arpos,bpos,&d1)) return 0; } else if (!dns_packet_getname(response,arpos,bpos + 2,&d1)) return 0; case_lowerb(d1,dns_domain_length(d1)); if (want(d1,DNS_T_A)) { cdb_findstart(&c); while (r = find(d1,0)) { if (r == -1) return 0; if (byte_equal(type,2,DNS_T_A)) { if (!response_rstart(d1,DNS_T_A,ttl)) return 0; if (!dobytes(4)) return 0; response_rfinish(RESPONSE_ADDITIONAL); } } } } uint16_unpack_big(x + 8,&u16); bpos += u16; } if (flagauthoritative && (response_len > 512)) { byte_zero(response + RESPONSE_ADDITIONAL,2); response_len = arpos; if (response_len > 512) { byte_zero(response + RESPONSE_AUTHORITY,2); response_len = aupos; } } return 1; }
int main (void) { stralloc indata = STRALLOC_ZERO ; unsigned int instate = 0 ; PROG = "s6-ftrigrd" ; if (ndelay_on(0) < 0) strerr_diefu2sys(111, "ndelay_on ", "0") ; if (ndelay_on(1) < 0) strerr_diefu2sys(111, "ndelay_on ", "1") ; if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ; { struct taia deadline, stamp ; taia_now(&stamp) ; taia_addsec(&deadline, &stamp, 2) ; if (!skaserver2_sync(&asyncout, FTRIGR_BANNER1, FTRIGR_BANNER1_LEN, FTRIGR_BANNER2, FTRIGR_BANNER2_LEN, &deadline, &stamp)) strerr_diefu1sys(111, "sync with client") ; } for (;;) { register unsigned int n = genalloc_len(ftrigio_t, &a) ; iopause_fd x[3 + n] ; unsigned int i = 0 ; int r ; x[0].fd = 0 ; x[0].events = IOPAUSE_EXCEPT | IOPAUSE_READ ; x[1].fd = 1 ; x[1].events = IOPAUSE_EXCEPT | (bufalloc_len(bufalloc_1) ? IOPAUSE_WRITE : 0) ; x[2].fd = bufalloc_fd(&asyncout) ; x[2].events = IOPAUSE_EXCEPT | (bufalloc_len(&asyncout) ? IOPAUSE_WRITE : 0) ; for (; i < n ; i++) { register ftrigio_t_ref p = genalloc_s(ftrigio_t, &a) + i ; p->xindex = 3 + i ; x[3+i].fd = p->trig.fd ; x[3+i].events = IOPAUSE_READ ; } r = iopause(x, 3 + n, 0, 0) ; if (r < 0) { cleanup() ; strerr_diefu1sys(111, "iopause") ; } /* client closed => exit */ if ((x[0].revents | x[1].revents) & IOPAUSE_EXCEPT) break ; /* client reading => flush pending data */ if (x[1].revents & IOPAUSE_WRITE) if ((bufalloc_flush(bufalloc_1) == -1) && !error_isagain(errno)) { cleanup() ; strerr_diefu1sys(111, "flush stdout") ; } if (x[2].revents & IOPAUSE_WRITE) if ((bufalloc_flush(&asyncout) == -1) && !error_isagain(errno)) { cleanup() ; strerr_diefu1sys(111, "flush asyncout") ; } /* scan listening ftrigs */ for (i = 0 ; i < genalloc_len(ftrigio_t, &a) ; i++) { register ftrigio_t_ref p = genalloc_s(ftrigio_t, &a) + i ; if (x[p->xindex].revents & IOPAUSE_READ) { char c ; register int r = sanitize_read(fd_read(p->trig.fd, &c, 1)) ; if (!r) continue ; if (r < 0) { trig(p->id, 'd', errno) ; remove(i--) ; } else if (!sredfa_feed(p->re, &p->dfastate, c)) { trig(p->id, 'd', ENOEXEC) ; remove(i--) ; } else if (p->dfastate & SREDFA_ACCEPT) { trig(p->id, '!', c) ; if (p->options & FTRIGR_REPEAT) p->dfastate = SREDFA_START ; else remove(i--) ; } } } /* client writing => get data and parse it */ if (buffer_len(buffer_0small) || x[0].revents & IOPAUSE_READ) { int r ; for (;;) { uint16 id ; r = sanitize_read(netstring_get(buffer_0small, &indata, &instate)) ; if (r <= 0) break ; if (indata.len < 3) { cleanup() ; strerr_dief1x(100, "invalid client request") ; } uint16_unpack_big(indata.s, &id) ; switch (indata.s[2]) /* protocol parsing */ { case 'U' : /* unsubscribe */ { register unsigned int i = genalloc_len(ftrigio_t, &a) ; for (; i ; i--) if (genalloc_s(ftrigio_t, &a)[i-1].id == id) break ; if (i) remove(i-1) ; answer(0) ; break ; } case 'L' : /* subscribe to path and match re */ { ftrigio_t f = FTRIGIO_ZERO ; uint32 pathlen, relen ; if (indata.len < 18) { answer(EPROTO) ; break ; } uint32_unpack_big(indata.s + 3, &f.options) ; uint32_unpack_big(indata.s + 7, &pathlen) ; uint32_unpack_big(indata.s + 11, &relen) ; if (((pathlen + relen + 16) != indata.len) || indata.s[15 + pathlen]) { answer(EPROTO) ; break ; } f.id = id ; if (!stralloc_0(&indata)) { answer(errno) ; break ; } f.re = sredfa_new() ; if (!f.re) { answer(errno) ; break ; } if (!sredfa_from_regexp(f.re, indata.s + 16 + pathlen) || !ftrig1_make(&f.trig, indata.s + 15)) { sredfa_delete(f.re) ; answer(errno) ; break ; } if (!genalloc_append(ftrigio_t, &a, &f)) { ftrigio_deepfree(&f) ; answer(errno) ; break ; } answer(0) ; break ; } default : { cleanup() ; strerr_dief1x(100, "invalid client request") ; } } indata.len = 0 ; } /* end loop: parse input from client */ if (r < 0) { if (errno == EPIPE) break ; /* client closed */ else { cleanup() ; strerr_diefu1sys(111, "read a netstring") ; } } } /* end if: stuff to read on stdin */ } /* end loop: main iopause */ cleanup() ; return 0 ; }
int main (int argc, char *argv[]) { int n = 0; time_t t = 0; struct sigaction sa; char qtype[2]; char qclass[2]; char header[12]; const char *x = NULL; unsigned int pos = 0; unsigned long long qnum = 0; sa.sa_handler = handle_term; sigaction (SIGINT, &sa, NULL); sigaction (SIGTERM, &sa, NULL); sa.sa_handler = SIG_IGN; sigaction (SIGPIPE, &sa, NULL); prog = strdup ((x = strrchr (argv[0], '/')) != NULL ? x + 1 : argv[0]); n = check_option (argc, argv); argc -= n; argv += n; if (mode & DAEMON) /* redirect stderr to a log file */ redirect_to_log (logfile, STDERR_FILENO); time (&t); memset (seed, 0, sizeof (seed)); strftime (seed, sizeof (seed), "%b-%d %Y %T %Z", localtime (&t)); warnx ("version %s: starting %s\n", VERSION, 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); dns_random_init (seed); axfr = env_get ("AXFR"); if (debug_level) warnx ("AXFR set to `%s'", axfr); x = env_get ("TCPREMOTEIP"); if (debug_level) warnx ("TCPREMOTEIP set to `%s'", x); if (x) ip4_scan (x, ip); else byte_zero (ip, 4); x = env_get ("TCPREMOTEPORT"); if (debug_level) warnx ("TCPREMOTEPORT set to `%s'", x); if (!x) x = "0"; scan_ulong (x, &port); droproot (); for (;;) { netread (tcpheader, 2); uint16_unpack_big (tcpheader, &len); if (len > 512) errx (-1, "excessively large request"); netread (buf, len); pos = dns_packet_copy (buf, len, 0, header, 12); if (!pos) errx (-1, "truncated request"); if (header[2] & 254) errx (-1, "bogus query"); if (header[4] || (header[5] != 1)) errx (-1, "bogus query"); pos = dns_packet_getname (buf, len, pos, &zone); if (!pos) errx (-1, "truncated request"); zonelen = dns_domain_length (zone); pos = dns_packet_copy (buf, len, pos, qtype, 2); if (!pos) errx (-1, "truncated request"); pos = dns_packet_copy (buf, len, pos, qclass, 2); if (!pos) errx (-1, "truncated request"); if (byte_diff(qclass, 2, DNS_C_IN) && byte_diff(qclass, 2, DNS_C_ANY)) errx (-1, "bogus query: bad class"); log_query (++qnum, ip, port, header, zone, qtype); if (byte_equal(qtype,2,DNS_T_AXFR)) { case_lowerb (zone, zonelen); fdcdb = open_read ("data.cdb"); if (fdcdb == -1) errx (-1, "could not read from file `data.cdb'"); doaxfr (header); close (fdcdb); } else { if (!response_query (zone, qtype, qclass)) err (-1, "could not allocate enough memory"); response[2] |= 4; case_lowerb (zone, zonelen); response_id (header); response[3] &= ~128; if (!(header[2] & 1)) response[2] &= ~1; if (!respond (zone, qtype, ip)) errx (-1, "could not find information in file `data.cdb'"); print (response, response_len); } } }
int main() { unsigned int pos; char header[12]; char qtype[2]; char qclass[2]; const char *x; droproot(FATAL); dns_random_init(seed); axfr = env_get("AXFR"); x = env_get("TCPREMOTEIP"); if (x && ip6_scan(x,ip)) ; else byte_zero(ip,16); x = env_get("TCPREMOTEPORT"); if (!x) x = "0"; scan_ulong(x,&port); for (;;) { netread(tcpheader,2); uint16_unpack_big(tcpheader,&len); if (len > 512) strerr_die2x(111,FATAL,"excessively large request"); netread(buf,len); pos = dns_packet_copy(buf,len,0,header,12); if (!pos) die_truncated(); if (header[2] & 254) strerr_die2x(111,FATAL,"bogus query"); if (header[4] || (header[5] != 1)) strerr_die2x(111,FATAL,"bogus query"); pos = dns_packet_getname(buf,len,pos,&zone); if (!pos) die_truncated(); zonelen = dns_domain_length(zone); pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) die_truncated(); pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) die_truncated(); if (byte_diff(qclass,2,DNS_C_IN) && byte_diff(qclass,2,DNS_C_ANY)) strerr_die2x(111,FATAL,"bogus query: bad class"); pos = check_edns0(header, buf, len, pos); if (!pos) die_truncated(); qlog(ip,port,header,zone,qtype," "); if (byte_equal(qtype,2,DNS_T_AXFR)) { case_lowerb(zone,zonelen); fdcdb = open_read("data.cdb"); if (fdcdb == -1) die_cdbread(); doaxfr(header); close(fdcdb); } else { if (!response_query(zone,qtype,qclass)) nomem(); response[2] |= 4; case_lowerb(zone,zonelen); response_id(header); response[3] &= ~128; if (!(header[2] & 1)) response[2] &= ~1; if (!respond(zone,qtype,ip)) die_outside(); print(response,response_len); } } }
unsigned int printrecord_cat(stralloc *out,char *buf,unsigned int len,unsigned int pos,char *q,char qtype[2]) { char *x; char misc[20]; uint16 datalen; uint16 u16; uint32 u32; unsigned int newpos; int i; unsigned char ch; pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; pos = dns_packet_copy(buf,len,pos,misc,10); if (!pos) return 0; uint16_unpack_big(misc + 8,&datalen); newpos = pos + datalen; if (q) { if (!dns_domain_equal(d,q)) return newpos; if (byte_diff(qtype,2,misc) && byte_diff(qtype,2,DNS_T_ANY)) return newpos; } if (!dns_domain_todot_cat(out,d)) return 0; if (!stralloc_cats(out," ")) return 0; uint32_unpack_big(misc + 4,&u32); if (!stralloc_catulong0(out,u32,0)) return 0; if (byte_diff(misc + 2,2,DNS_C_IN)) { if (!stralloc_cats(out," weird class\n")) return 0; return newpos; } x = 0; if (byte_equal(misc,2,DNS_T_NS)) x = " NS "; if (byte_equal(misc,2,DNS_T_PTR)) x = " PTR "; if (byte_equal(misc,2,DNS_T_CNAME)) x = " CNAME "; if (x) { pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; if (!stralloc_cats(out,x)) return 0; if (!dns_domain_todot_cat(out,d)) return 0; } else if (byte_equal(misc,2,DNS_T_MX)) { if (!stralloc_cats(out," MX ")) return 0; pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0; pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; uint16_unpack_big(misc,&u16); if (!stralloc_catulong0(out,u16,0)) return 0; if (!stralloc_cats(out," ")) return 0; if (!dns_domain_todot_cat(out,d)) return 0; } else if (byte_equal(misc,2,DNS_T_SOA)) { if (!stralloc_cats(out," SOA ")) return 0; pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; if (!dns_domain_todot_cat(out,d)) return 0; if (!stralloc_cats(out," ")) return 0; pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; if (!dns_domain_todot_cat(out,d)) return 0; pos = dns_packet_copy(buf,len,pos,misc,20); if (!pos) return 0; for (i = 0;i < 5;++i) { if (!stralloc_cats(out," ")) return 0; uint32_unpack_big(misc + 4 * i,&u32); if (!stralloc_catulong0(out,u32,0)) return 0; } } else if (byte_equal(misc,2,DNS_T_A)) { if (datalen != 4) { errno = error_proto; return 0; } if (!stralloc_cats(out," A ")) return 0; pos = dns_packet_copy(buf,len,pos,misc,4); if (!pos) return 0; for (i = 0;i < 4;++i) { ch = misc[i]; if (i) if (!stralloc_cats(out,".")) return 0; if (!stralloc_catulong0(out,ch,0)) return 0; } } else if (byte_equal(misc,2,DNS_T_AAAA)) { char ip6str[IP6_FMT]; int stringlen; if (datalen != 16) { errno = error_proto; return 0; } if (!stralloc_cats(out," AAAA ")) return 0; pos = dns_packet_copy(buf,len,pos,misc,16); if (!pos) return 0; stringlen=ip6_fmt(ip6str,misc); if (!stralloc_cats(out,ip6str)) return 0; } else { if (!stralloc_cats(out," ")) return 0; uint16_unpack_big(misc,&u16); if (!stralloc_catulong0(out,u16,0)) return 0; if (!stralloc_cats(out," ")) return 0; while (datalen--) { pos = dns_packet_copy(buf,len,pos,misc,1); if (!pos) return 0; if ((misc[0] >= 33) && (misc[0] <= 126) && (misc[0] != '\\')) { if (!stralloc_catb(out,misc,1)) return 0; } else { ch = misc[0]; misc[3] = '0' + (7 & ch); ch >>= 3; misc[2] = '0' + (7 & ch); ch >>= 3; misc[1] = '0' + (7 & ch); misc[0] = '\\'; if (!stralloc_catb(out,misc,4)) return 0; } } } if (!stralloc_cats(out,"\n")) return 0; if (pos != newpos) { errno = error_proto; return 0; } return newpos; }
int main(int argc,char **argv) { char *hostname; // char *portname; int opt; struct servent *se; char *x; unsigned long u; int s; int t; while ((opt = getopt(argc,argv,"4dDvqQhHrR1UXx:t:u:g:l:b:B:c:I:pPoO")) != opteof) switch(opt) { case 'b': scan_ulong(optarg,&backlog); break; case 'c': scan_ulong(optarg,&limit); break; case 'X': flagallownorules = 1; break; case 'x': fnrules = optarg; break; case 'B': banner = optarg; break; case 'd': flagdelay = 1; break; case 'D': flagdelay = 0; break; case 'v': verbosity = 2; break; case 'q': verbosity = 0; break; case 'Q': verbosity = 1; break; case 'P': flagparanoid = 0; break; case 'p': flagparanoid = 1; break; case 'O': flagkillopts = 1; break; case 'o': flagkillopts = 0; break; case 'H': flagremotehost = 0; break; case 'h': flagremotehost = 1; break; // case 'R': flagremoteinfo = 0; break; case 'r': flagremoteinfo = 1; break; case 't': scan_ulong(optarg,&timeout); break; case 'U': x = env_get("UID"); if (x) scan_ulong(x,&uid); x = env_get("GID"); if (x) scan_ulong(x,&gid); break; case 'u': scan_ulong(optarg,&uid); break; case 'g': scan_ulong(optarg,&gid); break; case 'I': netif=socket_getifidx(optarg); break; case '1': flag1 = 1; break; // case '4': noipv6 = 1; break; case '4': ipv4socket = 1; break; // case '6': forcev6 = 1; break; case 'l': localhost = optarg; break; default: usage(); } argc -= optind; argv += optind; if (!verbosity) buffer_2->fd = -1; hostname = *argv++; if (!hostname) usage(); if (str_equal(hostname,"")) hostname = "0"; x = *argv++; if (!x) usage(); if (!x[scan_ulong(x,&u)]) localport = u; else { se = getservbyname(x,"tcp"); if (!se) errint(EHARD,B("unable to figure out port number for ",x)); uint16_unpack_big((char*)&se->s_port,&localport); } if (!*argv) usage(); sig_block(sig_child); sig_catch(sig_child,sigchld); sig_catch(sig_term,sigterm); sig_ignore(sig_pipe); if (str_equal(hostname,"0")) { byte_zero(localip,sizeof localip); } else { if (!stralloc_copys(&tmp,hostname)) errmem; if (dns_ip6_qualify(&addresses,&fqdn,&tmp) == -1) errint(EHARD,B("temporarily unable to figure out IP address for ",hostname,": ")); if (addresses.len < 16) errint(EHARD,B("no IP address for ",hostname)); byte_copy(localip,16,addresses.s); if (ip6_isv4mapped(localip)) ipv4socket = 1; } s = socket_tcp(); if (s == -1) errint(EHARD,"unable to create socket: "); if (socket_bind_reuse(s,localip,localport,netif) == -1) errint(EHARD,"unable to bind: "); if (!ipv4socket) ipv4socket = ip6_isv4mapped(localip); if (socket_local(s,localip,&localport,&netif) == -1) errint(EHARD,"unable to get local address: "); if (socket_listen(s,backlog) == -1) errint(EHARD,"unable to listen: "); ndelay_off(s); if (gid) if (prot_gid(gid) == -1) errint(EHARD,"unable to set gid: "); if (uid) if (prot_uid(uid) == -1) errint(EHARD,"unable to set uid: "); localportstr[fmt_ulong(localportstr,localport)] = 0; if (flag1) { buffer_init(&b,write,1,bspace,sizeof bspace); buffer_puts(&b,localportstr); buffer_puts(&b,"\n"); buffer_flush(&b); } close(0); close(1); printstatus(); for (;;) { while (numchildren >= limit) sig_pause(); sig_unblock(sig_child); t = socket_accept(s,remoteip,&remoteport,&netif); sig_block(sig_child); if (t == -1) continue; ++numchildren; printstatus(); switch(fork()) { case 0: close(s); doit(t); if ((fd_move(0,t) == -1) || (fd_copy(1,0) == -1)) errint(EHARD,"unable to set up descriptors: "); sig_uncatch(sig_child); sig_unblock(sig_child); sig_uncatch(sig_term); sig_uncatch(sig_pipe); pathexec(argv); errint(EHARD,B("unable to run ",*argv,": ")); case -1: errlog(ESOFT,NOTICE,"unable to fork: "); --numchildren; printstatus(); } close(t); } }
int main(int argc,char * const *argv) { const char *hostname; int opt; struct servent *se; char *x; unsigned long u; int s; int t; io_opt = ssl_io_opt_default; io_opt.timeout = 3600; while ((opt = getopt(argc,argv,"46dDvqQhHrR1UXx:t:T:u:g:l:b:B:c:Z:pPoO3IiEeSsaAw:nNyYuUjJ")) != opteof) switch(opt) { case 'b': scan_ulong(optarg,&backlog); break; case 'c': scan_ulong(optarg,&limit); break; case 'X': flagallownorules = 1; break; case 'x': fnrules = optarg; break; case 'B': banner = optarg; break; case 'd': flagdelay = 1; break; case 'D': flagdelay = 0; break; case 'v': verbosity = 2; break; case 'q': verbosity = 0; break; case 'Q': verbosity = 1; break; case 'P': flagparanoid = 0; break; case 'p': flagparanoid = 1; break; case 'O': flagkillopts = 1; break; case 'o': flagkillopts = 0; break; case 'H': flagremotehost = 0; break; case 'h': flagremotehost = 1; break; case 'R': flagremoteinfo = 0; break; case 'r': flagremoteinfo = 1; break; case 't': scan_ulong(optarg,&timeout); break; case 'T': scan_ulong(optarg,&ssltimeout); break; case 'w': scan_uint(optarg,&io_opt.timeout); break; case 'U': x = env_get("UID"); if (x) scan_ulong(x,&uid); x = env_get("GID"); if (x) scan_ulong(x,&gid); break; case 'u': scan_ulong(optarg,&uid); break; case 'g': scan_ulong(optarg,&gid); break; case 'Z': netif=socket_getifidx(optarg); break; case '1': flag1 = 1; break; case '4': noipv6 = 1; break; case '6': forcev6 = 1; break; case 'l': localhost = optarg; break; case '3': flag3 = 1; break; case 'I': flagclientcert = 0; break; case 'i': flagclientcert = 1; break; case 'S': flagsslenv = 0; break; case 's': flagsslenv = 1; break; case 'E': flagtcpenv = 0; break; case 'e': flagtcpenv = 1; break; case 'n': case 'y': flagsslwait = 1; break; case 'N': case 'Y': flagsslwait = 0; break; case 'j': io_opt.just_shutdown = 1; break; case 'J': io_opt.just_shutdown = 0; break; default: usage(); } argc -= optind; argv += optind; if (!verbosity) buffer_2->fd = -1; hostname = *argv++; if (!hostname) usage(); if (str_equal(hostname,"")) hostname = "0"; x = *argv++; if (!x) usage(); prog = argv; if (!*argv) usage(); if (!x[scan_ulong(x,&u)]) localport = u; else { se = getservbyname(x,"tcp"); if (!se) strerr_die3x(111,FATAL,"unable to figure out port number for ",x); uint16_unpack_big((char*)&se->s_port,&localport); } if (x = env_get("VERIFYDEPTH")) { scan_ulong(x,&u); verifydepth = u; } if (x = env_get("CAFILE")) cafile = x; if (cafile && str_equal(cafile,"")) cafile = 0; if (x = env_get("CCAFILE")) ccafile = x; if (ccafile && str_equal(ccafile,"")) ccafile = 0; if (!flagclientcert) ccafile = 0; if (x = env_get("CADIR")) cadir = x; if (cadir && str_equal(cadir,"")) cadir= 0; if (x = env_get("CERTFILE")) certfile = x; if (certfile && str_equal(certfile,"")) certfile = 0; if (x = env_get("KEYFILE")) keyfile = x; if (keyfile && str_equal(keyfile,"")) keyfile = 0; if (x = env_get("DHFILE")) dhfile = x; if (dhfile && str_equal(dhfile,"")) dhfile = 0; if (x = env_get("CIPHERS")) ciphers = x; if (ciphers && str_equal(ciphers,"")) ciphers = 0; sig_block(sig_child); sig_catch(sig_child,sigchld); sig_catch(sig_term,sigterm); sig_ignore(sig_pipe); if (str_equal(hostname,"0")) { byte_zero(localip,sizeof localip); } else { if (!stralloc_copys(&tmp,hostname)) strerr_die2x(111,FATAL,"out of memory"); if (dns_ip6_qualify(&addresses,&fqdn,&tmp) == -1) strerr_die4sys(111,FATAL,"temporarily unable to figure out IP address for ",hostname,": "); if (addresses.len < 16) strerr_die3x(111,FATAL,"no IP address for ",hostname); byte_copy(localip,16,addresses.s); if (ip6_isv4mapped(localip)) noipv6=1; } s = socket_tcp6(); if (s == -1) strerr_die2sys(111,FATAL,"unable to create socket: "); if (socket_bind6_reuse(s,localip,localport,netif) == -1) strerr_die2sys(111,FATAL,"unable to bind: "); if (socket_local6(s,localip,&localport,&netif) == -1) strerr_die2sys(111,FATAL,"unable to get local address: "); if (socket_listen(s,backlog) == -1) strerr_die2sys(111,FATAL,"unable to listen: "); ndelay_off(s); localportstr[fmt_ulong(localportstr,localport)] = 0; if (flag1) { buffer_init(&b,buffer_unixwrite,1,bspace,sizeof bspace); buffer_puts(&b,localportstr); buffer_puts(&b,"\n"); buffer_flush(&b); } if (flag3) read_passwd(); ctx = ssl_server(); ssl_errstr(); if (!ctx) strerr_die2x(111,FATAL,"unable to create SSL context"); switch (ssl_certkey(ctx,certfile,keyfile,passwd_cb)) { case -1: strerr_die2x(111,FATAL,"unable to load certificate"); case -2: strerr_die2x(111,FATAL,"unable to load key"); case -3: strerr_die2x(111,FATAL,"key does not match certificate"); default: break; } if (!ssl_ca(ctx,cafile,cadir,verifydepth)) strerr_die2x(111,FATAL,"unable to load CA list"); if (!ssl_cca(ctx,ccafile)) strerr_die2x(111,FATAL,"unable to load client CA list"); if (!ssl_params(ctx,dhfile,rsalen)) strerr_die2x(111,FATAL,"unable to set cipher parameters"); if (!ssl_ciphers(ctx,ciphers)) strerr_die2x(111,FATAL,"unable to set cipher list"); if (verbosity >= 2) { strnum[fmt_ulong(strnum,getpid())] = 0; strnum2[fmt_ulong(strnum2,rsalen)] = 0; strerr_warn4("sslserver: cafile ",strnum," ",cafile,0); strerr_warn4("sslserver: ccafile ",strnum," ",ccafile,0); strerr_warn4("sslserver: cadir ",strnum," ",cadir,0); strerr_warn4("sslserver: cert ",strnum," ",certfile,0); strerr_warn4("sslserver: key ",strnum," ",keyfile,0); strerr_warn6("sslserver: param ",strnum," ",dhfile," ",strnum2,0); } close(0); open_read("/dev/null"); close(1); open_append("/dev/null"); printstatus(); for (;;) { while (numchildren >= limit) sig_pause(); sig_unblock(sig_child); t = socket_accept6(s,remoteip,&remoteport,&netif); sig_block(sig_child); if (t == -1) continue; ++numchildren; printstatus(); switch(fork()) { case 0: close(s); doit(t); strerr_die4sys(111,DROP,"unable to run ",*argv,": "); case -1: strerr_warn2(DROP,"unable to fork: ",&strerr_sys); --numchildren; printstatus(); } close(t); } }
int socket_accept4(int s,char *ip,uint16 *port) { struct sockaddr_in si; socklen_t len = sizeof si; int fd; #ifdef __MINGW32__ io_entry* e=array_get(&io_fds,sizeof(io_entry),s); if (e && e->inuse) { int sa2len; fd=-1; if (e->acceptqueued==1) { errno=EAGAIN; return -1; } if (e->acceptqueued==2) { incoming: /* incoming! */ { struct sockaddr* x,* y; GetAcceptExSockaddrs(e->inbuf,0,200,200,&x,&sa2len,&y,&len); if (len>sizeof(si)) len=sizeof(si); memcpy(&si,y,len); } fd=e->next_accept; e->next_accept=0; if (e->nonblock) { if (io_fd(fd)) { io_entry* f=array_get(&io_fds,sizeof(io_entry),fd); if (f) { f->nonblock=1; /* printf("setting fd %lu to non-blocking\n",(int)fd);*/ } } } } /* no accept queued, queue one now. */ if (e->next_accept==0) { e->next_accept=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if (e==-1) return winsock2errno(-1); } if (AcceptEx(s,e->next_accept,e->inbuf,0,200,200,&e->errorcode,&e->or)) goto incoming; if (WSAGetLastError() != ERROR_IO_PENDING) return winsock2errno(-1); e->acceptqueued=1; if (fd==-1) { errno=EAGAIN; return fd; } } else { #endif if ((fd=accept(s,(void*) &si,&len))==-1) return winsock2errno(-1); #ifdef __MINGW32__ } #endif if (ip) *(uint32*)ip = *(uint32*)&si.sin_addr; if (port) uint16_unpack_big((char *) &si.sin_port,port); return fd; }