static int irrelevant (const struct dns_transmit *d, const char *buf, unsigned int len) { unsigned int pos = 0; char out[12], *dn = NULL; if (!(pos = dns_packet_copy (buf, len, 0, out, 12))) return 1; if (byte_diff (out, 2, d->query + 2)) return 1; if (out[4] != 0) return 1; if (out[5] != 1) return 1; if (!(pos = dns_packet_getname (buf, len, pos, &dn))) return 1; if (!dns_domain_equal (dn, d->query + 14)) { alloc_free (dn); return 1; } alloc_free (dn); if (!(pos = dns_packet_copy (buf, len, pos, out, 4))) return 1; if (byte_diff (out, 2, d->qtype)) return 1; if (byte_diff (out + 2, 2, DNS_C_IN)) return 1; return 0; }
int skaclient2_startf (skaclient2_t_ref a, char const *prog, char const *const *argv, char const *const *envp, char const *before, unsigned int beforelen, char const *after, unsigned int afterlen, uint32 options, struct taia const *deadline, struct taia *stamp) { int fds[3] ; unsigned int pid = child_spawn2(prog, argv, envp, 0, 0, fds) ; register int e ; if (!pid) return 0 ; a->sync.pid = pid ; a->sync.options = options ; skaclientin_init(&a->sync.in, fds[0]) ; bufalloc_init(&a->sync.out, &fd_write, fds[1]) ; skaclientin_init(&a->async, fds[2]) ; { char tmp[beforelen] ; if (skaclientin_read(&a->sync.in, tmp, beforelen, deadline, stamp) < beforelen) { e = errno ; goto err ; } if (byte_diff(tmp, beforelen, before)) { e = EPROTO ; goto err ; } } { char tmp[afterlen] ; if (skaclientin_read(&a->async, tmp, afterlen, deadline, stamp) < afterlen) { e = errno ; goto err ; } if (byte_diff(tmp, afterlen, after)) { e = EPROTO ; goto err ; } } return 1 ; err: skaclient_end(&a->sync) ; skaclientin_end(&a->async) ; errno = e ; return 0 ; }
static int doit(char *q,char qtype[2],char ip[4]) { int r; uint32 dlen; unsigned int qlen; qlen = dns_domain_length(q); if (qlen > 255) return 0; /* impossible */ if (byte_diff(qtype,2,DNS_T_A) && byte_diff(qtype,2,DNS_T_ANY)) goto REFUSE; key[0] = '%'; byte_copy(key + 1,4,ip); r = cdb_find(&c,key,5); if (!r) r = cdb_find(&c,key,4); if (!r) r = cdb_find(&c,key,3); if (!r) r = cdb_find(&c,key,2); if (r == -1) return 0; key[0] = '+'; byte_zero(key + 1,2); if (r && (cdb_datalen(&c) == 2)) if (cdb_read(&c,key + 1,2,cdb_datapos(&c)) == -1) return 0; byte_copy(key + 3,qlen,q); case_lowerb(key + 3,qlen + 3); r = cdb_find(&c,key,qlen + 3); if (!r) { byte_zero(key + 1,2); r = cdb_find(&c,key,qlen + 3); } if (!r) goto REFUSE; if (r == -1) return 0; dlen = cdb_datalen(&c); if (dlen > 512) dlen = 512; if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return 0; dns_sortip(data,dlen); if (dlen > 12) dlen = 12; while (dlen >= 4) { dlen -= 4; if (!response_rstart(q,DNS_T_A,"\0\0\0\5")) return 0; if (!response_addbytes(data + dlen,4)) return 0; response_rfinish(RESPONSE_ANSWER); } return 1; REFUSE: response[2] &= ~4; response[3] &= ~15; response[3] |= 5; return 1; }
static int make_connection(char* ip,uint16 port,uint32 scope_id,int s) { int v6=byte_diff(ip,12,V4mappedprefix); if (v6) { if (s==-1) { s=socket_tcp6(); if (s==-1) return -1; } if (socket_connect6(s,ip,port,scope_id)==-1) { if (errno==EAGAIN || errno==EINPROGRESS || errno==EISCONN) return s; ++kaputt; if (errno!=ECONNREFUSED && errno!=ECONNRESET) carpsys("socket_connect6"); close(s); return -1; } } else { if (s==-1) { s=socket_tcp4(); if (s==-1) return -1; } if (socket_connect4(s,ip+12,port)==-1) { if (errno==EAGAIN || errno==EINPROGRESS || errno==EISCONN) return s; ++kaputt; if (errno!=ECONNREFUSED && errno!=ECONNRESET) carpsys("socket_connect6"); close(s); return -1; } } return s; }
int isboundary(void) /* returns 1 if line.len contains the mime bondary, 0 otherwise */ { if (line.s[0] == '-' && line.s[1] == '-' && line.len >= boundary.len + 3) if (!byte_diff(line.s + 2,boundary.len,boundary.s)) /* boundary */ return 1; return 0; }
unsigned int str_strn (char const *haystack, unsigned int hlen, char const *needle, unsigned int nlen) { register unsigned int i = 0 ; if (!nlen) return 0 ; if (hlen < nlen) return hlen ; hlen -= nlen ; for (; i <= hlen ; i++) if (!byte_diff(haystack+i, nlen, needle)) return i ; return hlen+nlen ; }
int dmarc_fetch(stralloc *out,const char *domain) { stralloc_copys(&ddomain,"_dmarc."); stralloc_cats(&ddomain,domain); if (dns_txt(out,&ddomain) < 0) return -1; /* Check if it's really a DMARC record */ if (out->len < 10) return 0; if (byte_diff(out->s,9,"v=DMARC1;")) return 0; return 1; }
static int find(char *d,int flagwild) { int r; char ch; struct tai cutoff; char ttd[8]; char ttlstr[4]; char recordloc[2]; double newttl; for (;;) { r = cdb_findnext(&c,d,dns_domain_length(d)); if (r <= 0) return r; dlen = cdb_datalen(&c); if (dlen > sizeof data) return -1; if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return -1; dpos = dns_packet_copy(data,dlen,0,type,2); if (!dpos) return -1; dpos = dns_packet_copy(data,dlen,dpos,&ch,1); if (!dpos) return -1; if ((ch == '=' + 1) || (ch == '*' + 1)) { --ch; dpos = dns_packet_copy(data,dlen,dpos,recordloc,2); if (!dpos) return -1; if (byte_diff(recordloc,2,clientloc)) continue; } if (flagwild != (ch == '*')) continue; dpos = dns_packet_copy(data,dlen,dpos,ttlstr,4); if (!dpos) return -1; uint32_unpack_big(ttlstr,&ttl); dpos = dns_packet_copy(data,dlen,dpos,ttd,8); if (!dpos) return -1; if (byte_diff(ttd,8,"\0\0\0\0\0\0\0\0")) { tai_unpack(ttd,&cutoff); if (ttl == 0) { if (tai_less(&cutoff,&now)) continue; tai_sub(&cutoff,&cutoff,&now); newttl = tai_approx(&cutoff); if (newttl <= 2.0) newttl = 2.0; if (newttl >= 3600.0) newttl = 3600.0; ttl = newttl; } else if (!tai_less(&cutoff,&now)) continue; } return 1; } }
int address_diff(struct address *p,struct address *q) { int r; r = byte_diff(p->location,2,q->location); if (r < 0) return -1; if (r > 0) return 1; if (p->namelen < q->namelen) return -1; if (p->namelen > q->namelen) return 1; return case_diffb(p->name,p->namelen,q->name); }
static int doit(void) { unsigned int pos; char header[12]; char qtype[2]; char qclass[2]; if (len >= sizeof buf) goto NOQ; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) goto NOQ; if (header[2] & 128) goto NOQ; if (header[4]) goto NOQ; if (header[5] != 1) goto NOQ; pos = dns_packet_getname(buf,len,pos,&q); if (!pos) goto NOQ; pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) goto NOQ; pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) goto NOQ; if (!response_query(q,qtype,qclass)) goto NOQ; response_id(header); if (byte_equal(qclass,2,DNS_C_IN)) response[2] |= 4; else if (byte_diff(qclass,2,DNS_C_ANY)) goto WEIRDCLASS; response[3] &= ~128; if (!(header[2] & 1)) response[2] &= ~1; if (header[2] & 126) goto NOTIMP; if (byte_equal(qtype,2,DNS_T_AXFR)) goto NOTIMP; case_lowerb(q,dns_domain_length(q)); if (!respond(q,qtype,ip)) { qlog(ip,port,header,q,qtype," - "); return 0; } qlog(ip,port,header,q,qtype," + "); return 1; NOTIMP: response[3] &= ~15; response[3] |= 4; qlog(ip,port,header,q,qtype," I "); return 1; WEIRDCLASS: response[3] &= ~15; response[3] |= 1; qlog(ip,port,header,q,qtype," C "); return 1; NOQ: qlog(ip,port,"\0\0","","\0\0"," / "); return 0; }
static int packetquery(char *buf,unsigned int len,char **q,char qtype[2],char qclass[2],char id[2]) { unsigned int pos; char header[12]; errno = error_proto; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return 0; if (header[2] & 128) return 0; /* must not respond to responses */ if (!(header[2] & 1)) return 0; /* do not respond to non-recursive queries */ if (header[2] & 120) return 0; if (header[2] & 2) return 0; if (byte_diff(header + 4,2,"\0\1")) return 0; pos = dns_packet_getname(buf,len,pos,q); if (!pos) return 0; pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) return 0; pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) return 0; if (byte_diff(qclass,2,DNS_C_IN) && byte_diff(qclass,2,DNS_C_ANY)) return 0; byte_copy(id,2,header); return 1; }
int main(int argc,char *argv[]) { const char* dir; int fd; int match; unsigned long msgsize = 0L; int opt; while ((opt = getopt(argc,argv,"vV")) != opteof) { switch(opt) { case 'v': case 'V': strerr_die2x(0, "ezmlm-import version: ",auto_version); default: die_usage(); } } if (argc - optind != 2) die_usage(); if ((fd = open_read(argv[optind+1])) == -1) strerr_die4sys(111,FATAL,ERR_OPEN,argv[optind+1],": "); substdio_fdbuf(&ssin,read,fd,inputbuf,sizeof inputbuf); startup(dir = argv[optind]); lockfile("lock"); getconf_ulong2(&msgnum,&cumsize,"num",0,dir); fd = 0; while (getln(&ssin,&line,&match,'\n') == 0 && match) { if (line.len > 5 && byte_diff(line.s,5,"From ") == 0) { if (fd > 0) { if (substdio_flush(&ssarchive) == -1 || fchmod(fd,MODE_ARCHIVE|0700) == -1 || close(fd) == -1) strerr_die4sys(111,FATAL,ERR_WRITE,fnaf.s,": "); fd = 0; } ++msgnum; cumsize += (msgsize + 128L) >> 8; msgsize = 0L; fd = openone(msgnum); } else if (fd > 0) { substdio_put(&ssarchive,line.s,line.len); msgsize += line.len; } }
static int thistcp (struct dns_transmit *d) { struct taia now; const char *ip = NULL; socketfree (d); packetfree (d); 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_tcp (); if (!d->s1) { dns_transmit_free (d); return -1; } if (randombind (d) == -1) { dns_transmit_free (d); return -1; } taia_now (&now); taia_uint (&d->deadline, 10); taia_add (&d->deadline, &d->deadline, &now); if (socket_connect4 (d->s1 - 1, ip, 53) == 0) { d->pos = 0; d->tcpstate = 2; return 0; } if (errno == error_inprogress || errno == error_wouldblock) { d->tcpstate = 1; return 0; } socketfree(d); } } dns_transmit_free(d); return -1; }
struct pminisock *pminisock_lookup(struct sock *sk, __u32 seqno, struct iphdr *iph, struct tcphdr *th) { struct ParsedPMinisock_cell *cell; struct pminisock_key key; ParsedPMinisock_cache.evictContext = sk; #ifdef SOCKET_KEY key.sk = sk; #endif key.seq = seqno; // printk("looking up seqno = %u\n", seqno); if(ParsedPMinisock_find_helper(&key, &cell)) { #if 0 if(CACHE_COMPARISON && (WireContinuation_inOutComp(cont, &cell->elem) != 0)) { printk("mismatch between input and continuation cache\n");; byte_diff(cont->hmac_start, cell->elem.copy_start, WIRECONT_MAC_LEN); } if(cont->tokenCounterBase != cell->elem.tokenCounterBase) { printk("Continuation (%d) hit, but %lld != %lld\n", cell->key, cont->tokenCounterBase, cell->elem.tokenCounterBase); return 0; } #endif // Invariant: cache implies not in any event queue struct pminisock *pmsk = cell->elem.pmsk; BUG_TRAP(pmsk->refCnt == 1); if(!( // seqno match is already verified pmsk->daddr == iph->saddr && pmsk->dest == th->source)) { printk("flow validation failed\n"); return NULL; } if(trickles_ratelimit()) { printk("Pminisock lookup does not perform validation yet\n"); } // to enforce above invariant, we delete the cell from the cache ParsedPMinisock_deleteCell(cell); return pmsk; } else { // printk("Could not find\n"); } return NULL; }
int timed_ancil_fd_sandwiched_recv (int fdsock, char const *before, unsigned int beforelen, char const *after, unsigned int afterlen, struct taia const *deadline, struct taia *stamp) { unsigned int maxlen = beforelen > afterlen ? beforelen : afterlen ; char buf[maxlen] ; buffer b = BUFFER_INIT(&fd_read, fdsock, buf, maxlen) ; int p ; { char gotbefore[beforelen] ; if (timed_buffer_get(&b, gotbefore, beforelen, deadline, stamp) < beforelen) return -1 ; if (byte_diff(gotbefore, beforelen, before)) return (errno = EPROTO, -1) ; } if (!timed_ancil_fd_recv(fdsock, &p, deadline, stamp)) return -1 ; if (ndelay_on(p) < 0) { register int e = errno ; fd_close(p) ; errno = e ; return -1 ; } { char gotafter[afterlen] ; if (timed_buffer_get(&b, gotafter, afterlen, deadline, stamp) < afterlen) { register int e = errno ; fd_close(p) ; errno = e ; return -1 ; } if (byte_diff(gotafter, afterlen, after)) { fd_close(p) ; return (errno = EPROTO, -1) ; } } return p ; }
static int match(struct cdb *c, const char *key, ut32 len, ut32 pos) { char buf[32]; const size_t szb = sizeof buf; while (len > 0) { int n = (szb>len)? len: szb; if (!cdb_read (c, buf, n, pos)) return -1; if (byte_diff (buf, n, key)) return 0; pos += n; key += n; len -= n; } return 1; }
static int match(struct cdb *c,char *key,unsigned int len,uint32 pos) { char buf[32]; int n; while (len > 0) { n = sizeof buf; if (n > len) n = len; if (cdb_read(c,buf,n,pos) == -1) return -1; if (byte_diff(buf,n,key)) return 0; pos += n; key += n; len -= n; } return 1; }
static int make_connection(char* ip,uint16 port,uint32 scope_id) { int v6=byte_diff(ip,12,V4mappedprefix); int s; if (v6) { s=socket_tcp6(); if (s==-1) panic("socket_tcp6()"); ndelay_off(s); if (bindport) { for (;;) { int r=socket_bind6_reuse(s,V6any,bindport,0); if (++bindport<1024) bindport=1024; if (r==0) break; if (errno!=EADDRINUSE) panic("socket_bind6"); } } if (socket_connect6(s,ip,port,scope_id)==-1) { carp("socket_connect6"); close(s); return -1; } } else { s=socket_tcp4(); if (s==-1) panic("socket_tcp4()"); ndelay_off(s); if (bindport) { for (;;) { int r=socket_bind4_reuse(s,V6any,bindport); if (++bindport<1024) bindport=1024; if (r==0) break; if (errno!=EADDRINUSE) panic("socket_bind4"); } } if (socket_connect4(s,ip+12,port)==-1) { carp("socket_connect4"); close(s); return -1; } } return s; }
int main(int argc,char *argv[]) { int fd; int match; unsigned long msgsize = 0L; int opt; stralloc line = {0}; substdio ssin; char inputbuf[4096]; unsigned long msgnum; unsigned long cumsize; opt = getconfopt(argc,argv,options,1,0); switch (argc - opt) { case 0: substdio_fdbuf(&ssin,read,0,inputbuf,sizeof inputbuf); break; case 1: if ((fd = open_read(argv[opt])) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_OPEN,argv[opt])); substdio_fdbuf(&ssin,read,fd,inputbuf,sizeof inputbuf); break; default: die_usage(); } lockfile("lock"); getconf_ulong2(&msgnum,&cumsize,"num",0); fd = 0; while (getln(&ssin,&line,&match,'\n') == 0 && match) { if (line.len > 5 && byte_diff(line.s,5,"From ") == 0) { flushit(fd); ++msgnum; cumsize += (msgsize + 128L) >> 8; msgsize = 0L; fd = openone(msgnum); } else if (fd > 0) {
int skaclient_server_ack (unixmessage_t const *clientmsg, unixmessage_sender_t *out, unixmessage_sender_t *asyncout, char const *before, unsigned int beforelen, char const *after, unsigned int afterlen) { int fd[2] ; unixmessage_t m = { .s = (char *)after, .len = afterlen, .fds = fd, .nfds = 1 } ; static unsigned char const bits = 0xff ; if (clientmsg->nfds || clientmsg->len != beforelen || byte_diff(clientmsg->s, beforelen, before)) return (errno = EPROTO, 0) ; if (ipc_pair_nbcoe(fd) < 0) return 0 ; unixmessage_sender_init(asyncout, fd[1]) ; if (!unixmessage_put_and_close(out, &m, &bits)) { int e = errno ; fd_close(fd[1]) ; fd_close(fd[0]) ; errno = e ; return 0 ; } return 1 ; }
static void sort(proc_entry **pe, unsigned int len){ unsigned int i, j; stralloc *a, *b; proc_entry *tmp; if (len <= 1) return; for(i = 0; i < len - 1; ++i){ for(j = len - 1; j > i; --j){ a = &pe[j-1]->name; b = &pe[j]->name; /* compare */ if (byte_diff(a->s, min(a->len, b->len), b->s) > 0){ /* swap */ tmp = pe[j-1]; pe[j-1] = pe[j]; pe[j] = tmp; } } } }
int main(int argc,char *argv[]) { int fd; int match; unsigned long msgsize = 0L; int opt; opt = getconfopt(argc,argv,options,1,0); if (argc - opt != 1) die_usage(); if ((fd = open_read(argv[opt])) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_OPEN,argv[opt])); substdio_fdbuf(&ssin,read,fd,inputbuf,sizeof inputbuf); lockfile("lock"); getconf_ulong2(&msgnum,&cumsize,"num",0); fd = 0; while (getln(&ssin,&line,&match,'\n') == 0 && match) { if (line.len > 5 && byte_diff(line.s,5,"From ") == 0) { if (fd > 0) { if (substdio_flush(&ssarchive) == -1 || fchmod(fd,MODE_ARCHIVE|0700) == -1 || close(fd) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnaf.s)); fd = 0; } ++msgnum; cumsize += (msgsize + 128L) >> 8; msgsize = 0L; fd = openone(msgnum); } else if (fd > 0) { substdio_put(&ssarchive,line.s,line.len); msgsize += line.len; } }
static int cb_foreach_i(void* ptr, const void* key, size_t keylen, int (*match_cb)(const void* match, const void* key, size_t keylen, void*), void* data) { int result = 0; if(decode_pointer(&ptr) == INTERNAL_NODE) { struct critbit_node* node = (struct critbit_node*)ptr; result = cb_foreach_i(node->child[0], key, keylen, match_cb, data); if(!result) { result = cb_foreach_i(node->child[1], key, keylen, match_cb, data); } } else { /* reached an external node */ void* match; size_t len; from_external_node(ptr, &match, &len); if(len >= keylen && byte_diff(key, keylen, match) == 0) { return match_cb(match, key, keylen, data); } } return result; }
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 WireContinuation_lookup(struct WireContinuation *cont, struct iphdr *iph, struct tcphdr *th) { CachedWireContinuationKey key = seqnoToKey(cont->seq); struct Continuation_cell *cell; if(Continuation_find_helper(&key, &cell)) { #if 0 if(CACHE_COMPARISON && (WireContinuation_inOutComp(cont, &cell->elem) != 0)) { printk("mismatch between input and continuation cache\n");; byte_diff(cont->hmac_start, cell->elem.copy_start, WIRECONT_MAC_LEN); } if(cont->tokenCounterBase != cell->elem.tokenCounterBase) { printk("Continuation (%d) hit, but %lld != %lld\n", cell->key, cont->tokenCounterBase, cell->elem.tokenCounterBase); return 0; } #endif if(!WireContinuation_checkAndCopyOut(cont, &cell->elem, iph, th)) { if(trickles_ratelimit()) { printk("Sequence number and flow ID did not match\n"); return 0; } } #if 0 if(trickles_ratelimit()) { printk("isolating memory corruption\n"); } return 1; #endif Continuation_deleteCell(cell); return 1; } //printk("Continuation (%d) missed\n", cont->seq); return 0; }
static int thistcp(struct dns_transmit *d) { struct taia now; const char *ip; socketfree(d); packetfree(d); for (;d->curserver < 16;++d->curserver) { ip = d->servers + 16 * d->curserver; if (byte_diff(ip,16,V6any)) { d->query[2] = dns_random(256); d->query[3] = dns_random(256); d->s1 = 1 + socket_tcp6(); if (!d->s1) { dns_transmit_free(d); return -1; } if (randombind(d) == -1) { dns_transmit_free(d); return -1; } taia_now(&now); taia_uint(&d->deadline,10); taia_add(&d->deadline,&d->deadline,&now); if (socket_connect6(d->s1 - 1,ip,53,d->scope_id) == 0) { d->tcpstate = 2; return 0; } if ((errno == error_inprogress) || (errno == error_wouldblock)) { d->tcpstate = 1; return 0; } socketfree(d); } } dns_transmit_free(d); return -1; }
extern int stralloc_starts(stralloc *sa,const char *in) { register size_t len=str_len(in); return (len<=sa->len && !byte_diff(sa->s,len,in)); }
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; }
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; }
static void do_ed(char *action) { datetime_sec u; int flaggoodfield; int fd; char *x, *y; char *cp,*cplast,*cpnext,*cpafter; int flagdone; unsigned int len; const char *fname; unsigned int i; x = action + LENGTH_ED; x += scan_ulong(x,&u); if ((u > when) || (u < when - 100000)) die_cookie(); if (*x == '.') ++x; fname = x; x += str_chr(x,'.'); if (!*x) die_cookie(); *x = (char) 0; ++x; stralloc_copys(&fnedit,"text/"); stralloc_cats(&fnedit,fname); stralloc_0(&fnedit); y = fnedit.s + 5; /* after "text/" */ while (*++y) { /* Name should be guaranteed by the cookie, */ /* but better safe than sorry ... */ if (((*y > 'z') || (*y < 'a')) && (*y != '_')) strerr_die2x(100,FATAL,MSG(ERR_BAD_NAME)); if (*y == '_') *y = '-'; } lock(); /* file must not change while here */ switch (slurp(fnedit.s,&text,1024)) { case -1: strerr_die2sys(111,FATAL,MSG1(ERR_READ,fnedit.s)); case 0: strerr_die5x(100,FATAL,dir,"/",fnedit.s,MSG(ERR_NOEXIST)); } stralloc_copy(&line,&text); subst_nuls(&line); stralloc_cat(&line,&fnedit); /* including '\0' */ strnum[fmt_ulong(strnum,(unsigned long) u)] = 0; cookie(hash,key.s,key.len,strnum,line.s,"-e"); if (str_len(x) != COOKIE) die_cookie(); if (byte_diff(hash,COOKIE,x)) die_cookie(); /* cookie is ok, file exists, lock's on, new file ends in '_' */ stralloc_copys(&fneditn,fnedit.s); stralloc_append(&fneditn,'_'); stralloc_0(&fneditn); fd = open_trunc(fneditn.s); if (fd == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fneditn.s)); substdio_fdbuf(&sstext,write,fd,textbuf,sizeof(textbuf)); stralloc_copys("ed,""); /* clear */ stralloc_copys(&text,""); for (;;) { /* get message body */ if (getln(&ssin,&line,&match,'\n') == -1) strerr_die2sys(111,FATAL,MSG(ERR_READ_INPUT)); if (!match) break; stralloc_cat(&text,&line); } if (encin) { /* decode if necessary */ if (encin == 'B') decodeB(text.s,text.len,&line); else decodeQ(text.s,text.len,&line); stralloc_copy(&text,&line); } cp = text.s; cpafter = text.s+text.len; flaggoodfield = 0; flagdone = 0; len = 0; while ((cpnext = cp + byte_chr(cp,cpafter-cp,'\n')) != cpafter) { i = byte_chr(cp,cpnext-cp,'%'); if (i != (unsigned int) (cpnext - cp)) { if (!flaggoodfield) { /* MSG(TXT_EDIT_START)/END */ if (case_startb(cp+i,cpnext-cp-i,MSG(TXT_EDIT_START))) { /* start tag. Store users 'quote characters', e.g. '> ' */ stralloc_copyb("ed,cp,i); flaggoodfield = 1; cp = cpnext + 1; continue; } } else if (case_startb(cp+i,cpnext-cp-i,MSG(TXT_EDIT_END))) { flagdone = 1; break; } } if (flaggoodfield) { if ((len += cpnext - cp - quoted.len + 1) > MAXEDIT) strerr_die1x(100,MSG(ERR_EDSIZE)); if (quoted.len && cpnext-cp >= (int) quoted.len && !str_diffn(cp,quoted.s,quoted.len)) cp += quoted.len; /* skip quoting characters */ cplast = cpnext - 1; if (*cplast == '\r') /* CRLF -> '\n' for base64 encoding */ *cplast = '\n'; else ++cplast; if (substdio_put(&sstext,cp,cplast-cp+1) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fneditn.s)); } cp = cpnext + 1; } if (!flagdone) strerr_die2x(100,FATAL,MSG(ERR_NO_MARK)); if (substdio_flush(&sstext) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fneditn.s)); if (fsync(fd) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_SYNC,fneditn.s)); if (fchmod(fd, 0600) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_CHMOD,fneditn.s)); if (close(fd) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_CLOSE,fneditn.s)); wrap_rename(fneditn.s,fnedit.s); unlock(); hdr_subject(MSG1(SUB_EDIT_SUCCESS,fname)); hdr_ctboundary(); copy(&qq,"text/top",flagcd); copy_act("text/edit-done"); copybottom(0); qmail_to(&qq,sender); /* not necessarily from mod */ }