static adns_status mkquery_header(adns_state ads, vbuf * vb, int *id_r, int qdlen) { int id; byte *rqp; if (!adns__vbuf_ensure(vb, DNS_HDRSIZE + qdlen + 4)) return adns_s_nomemory; vb->used = 0; MKQUERY_START(vb); *id_r = id = (ads->nextid++) & 0x0ffff; MKQUERY_ADDW(id); MKQUERY_ADDB(0x01); /* QR=Q(0), OPCODE=QUERY(0000), !AA, !TC, RD */ MKQUERY_ADDB(0x00); /* !RA, Z=000, RCODE=NOERROR(0000) */ MKQUERY_ADDW(1); /* QDCOUNT=1 */ MKQUERY_ADDW(0); /* ANCOUNT=0 */ MKQUERY_ADDW(0); /* NSCOUNT=0 */ MKQUERY_ADDW(0); /* ARCOUNT=0 */ MKQUERY_STOP(vb); return adns_s_ok; }
void adns__querysend_tcp(adns_query qu, struct timeval now) { byte length[2]; #if 0 struct iovec iov[2]; #endif int wr, wr2 = 0, r; adns_state ads; if (qu->ads->tcpstate != server_ok) return; assert(qu->state == query_tcpw); length[0]= (qu->query_dglen&0x0ff00U) >>8; length[1]= (qu->query_dglen&0x0ff); ads= qu->ads; if (!adns__vbuf_ensure(&ads->tcpsend,ads->tcpsend.used+qu->query_dglen+2)) return; qu->retries++; /* Reset idle timeout. */ ads->tcptimeout.tv_sec= ads->tcptimeout.tv_usec= 0; if (ads->tcpsend.used) { wr= 0; } else { #if 0 iov[0].iov_base= (char *)length; iov[0].iov_len= 2; iov[1].iov_base= (char *)qu->query_dgram; iov[1].iov_len= qu->query_dglen; wr= writev(qu->ads->tcpsocket,iov,2); #endif wr = write(qu->ads->tcpsocket, (char *)length, 2); if (wr > 0) wr2 = write(qu->ads->tcpsocket, (char *)qu->query_dgram, qu->query_dglen); if (wr < 0 || wr2 < 0) { if (!(errno == EAGAIN || errno == EINTR || errno == ENOSPC || errno == ENOBUFS || errno == ENOMEM)) { adns__tcp_broken(ads,"write",strerror(errno)); return; } wr= 0; } } if (wr<2) { r= adns__vbuf_append(&ads->tcpsend,length,2-wr); assert(r); wr= 0; } else { wr-= 2; } if (wr<qu->query_dglen) { r= adns__vbuf_append(&ads->tcpsend,qu->query_dgram+wr,qu->query_dglen-wr); assert(r); } }
void adns__querysend_tcp(adns_query qu, struct timeval now) { byte length[2]; #ifndef WIN32 struct iovec iov[2]; #endif int wr, r; adns_state ads; if (qu->ads->tcpstate != server_ok) return; assert(qu->state == query_tcpw); length[0] = (qu->query_dglen & 0x0ff00U) >> 8; length[1] = (qu->query_dglen & 0x0ff); ads = qu->ads; if( !adns__vbuf_ensure( &ads->tcpsend, ads->tcpsend.used + qu->query_dglen + 2 ) ) return; qu->retries++; /* Reset idle timeout. */ ads->tcptimeout.tv_sec = ads->tcptimeout.tv_usec = 0; if (ads->tcpsend.used) { wr = 0; } else { #ifdef WIN32 char *buf = NULL; buf = (char *)ns_malloc((2 + qu->query_dglen)); os_memcpy(buf, length, 2); os_memcpy((buf + 2), qu->query_dgram, qu->query_dglen); wr = os_sock_write(qu->ads->tcpsocket, buf, (2 + qu->query_dglen)); errno = os_sock_errno; ns_free(buf); #else iov[0].iov_base = length; iov[0].iov_len = 2; iov[1].iov_base = qu->query_dgram; iov[1].iov_len = qu->query_dglen; adns__sigpipe_protect(qu->ads); wr = writev(qu->ads->tcpsocket, iov, 2); #endif adns__sigpipe_unprotect(qu->ads); if (wr < 0) { if (! (errno == EAGAIN || errno == OS_SOCK_EINTR || errno == ENOSPC || errno == OS_SOCK_ENOBUFS || errno == ENOMEM)) { adns__tcp_broken(ads, "write", strerror(errno)); return; } wr = 0; } } if( wr < 2 ) { r = adns__vbuf_append( &ads->tcpsend, length, 2 - wr ); assert( r ); wr = 0; } else { wr -= 2; } if ( wr < qu->query_dglen ) { r = adns__vbuf_append( &ads->tcpsend, qu->query_dgram + wr, qu->query_dglen - wr ); assert( r ); } }