xfer.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,802 行 · 第 1/3 页
C
1,802 行
return XFER_FAIL; } } #else#ifdef ULTRIXFUNC if ((n = res_mkquery(QUERY, zp->z_origin, C_ANY, T_SOA, (char *)NULL, 0, NULL, buf, bufsize)) < 0) { if (!quiet) syslog(LOG_ERR, "zone %s: res_mkquery T_SOA failed", zp->z_origin); (void) close(s); (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); return XFER_FAIL; }#else ULTRIXFUNC if ((n = res_mkquery(QUERY, zp->z_origin, C_IN, T_SOA, (char *)NULL, 0, NULL, buf, bufsize)) < 0) { if (!quiet) syslog(LOG_ERR, "zone %s: res_mkquery T_SOA failed", zp->z_origin); (void) close(s); (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); return XFER_FAIL; }#endif ULTRIXFUNC#endif AUTHEN /* * Send length & message for zone transfer */ if (writemsg(s, buf, n) < 0) { (void) close(s); error++;#ifdef DEBUG if (debug >= 2) (void)fprintf(ddt,"writemsg failed\n");#endif continue; } /* * Get out your butterfly net and catch the SOA */ cp = buf; l = sizeof(u_short); read_interrupted = 0; while (l > 0) {#ifdef DEBUG if (debug > 10) (void)fprintf(ddt,"Before setitimer\n");#endif (void) setitimer(ITIMER_REAL, &ival, (struct itimerval *)NULL);#ifdef DEBUG if (debug > 10) (void)fprintf(ddt,"Before recv(l = %d)\n",n);#endif errno = 0; if ((n = recv(s, (char *)cp, l, 0)) > 0) { cp += n; l -= n; } else {#ifdef DEBUG if (debug > 10) (void)fprintf(ddt,"bad recv->%d, errno= %d, read_interrupt=%d\n", n, errno, read_interrupted);#endif#ifdef ULTRIXFUNC (void) close(s);#endif ULTRIXFUNC if (n == -1 && errno == EINTR && !read_interrupted) continue; error++;#ifdef DEBUG if(errno && debug) (void)fprintf(ddt,"bad recv->%d, errno= %d, read_interrupt=%d\n", n, errno, read_interrupted); else if (debug) (void)fprintf(ddt,"recv timeout occurred, read_interrupt=%d\n", read_interrupted);#endif break; } } (void) setitimer(ITIMER_REAL, &zeroival, (struct itimerval *)NULL); if (error) { (void) close(s); continue; } if ((len = htons(*(u_short *)buf)) == 0) { (void) close(s); continue; } if (len > bufsize) { if ((buf = (u_char *)realloc(buf, len)) == NULL) { syslog(LOG_ERR, "malloc(%u) failed for SOA from server %s, zone %s\n", len, inet_ntoa(sin.sin_addr), zp->z_origin); (void) close(s); continue; } bufsize = len; } l = len; cp = buf; while (l > 0) { (void) setitimer(ITIMER_REAL, &ival, (struct itimerval *)NULL); errno = 0; if ((n = recv(s, (char *)cp, l, 0)) > 0) { cp += n; l -= n; } else {#ifdef ULTRIXFUNC (void) close(s);#endif ULTRIXFUNC if (errno == EINTR && !read_interrupted) continue; error++;#ifdef DEBUG if (debug > 10) (void)fprintf(ddt, "recv failed: n= %d, errno = %d\n", n, errno);#endif#ifdef DEBUG if(errno && debug) (void)fprintf(ddt,"bad recv->%d, errno= %d, read_interrupt=%d\n", n, errno, read_interrupted); else if (debug) (void)fprintf(ddt,"recv timeout occurred, read_interrupt=%d\n", read_interrupted);#endif break; } } (void) setitimer(ITIMER_REAL, &zeroival, (struct itimerval *)NULL); if (error) { (void) close(s); continue; }#ifdef DEBUG if (debug >= 3) { (void)fprintf(ddt,"len = %d\n", len); fp_query(buf, ddt); }#endif DEBUG hp = (HEADER *) buf; ancount = ntohs(hp->ancount); aucount = ntohs(hp->nscount); /* * close socket if: * 1) rcode != NOERROR * 2) not an authority response * 3) both the number of answers and authority count < 1) *//* if (hp->rcode != NOERROR || !(hp->aa) || (ancount < 1 && aucount < 1)) { */ /* None of the additional conditions above can be met with a C_ANY query */ if (hp->rcode != NOERROR ) { if (!quiet) syslog(LOG_ERR, "%s from %s, zone %s: rcode %d, aa %d, ancount %d, aucount %d\n", "bad response to SOA query", inet_ntoa(sin.sin_addr), zp->z_origin, hp->rcode, hp->aa, ancount, aucount);#ifdef DEBUG if (debug) fprintf(ddt, "%s from %s, zone %s: rcode %d, aa %d, ancount %d, aucount %d\n", "bad response to SOA query", inet_ntoa(sin.sin_addr), zp->z_origin, hp->rcode, hp->aa, ancount, aucount);#endif DEBUG (void) close(s); error++; continue; } zp_start = *zp;#ifdef AUTHEN if (len < sizeof(HEADER) + ((hp->opcode == AQUERY) ? AQFIXEDSZ : QFIXEDSZ)) {#else AUTHEN if (len < sizeof(HEADER) + QFIXEDSZ) {#endif AUTHEN badsoa: if (!quiet) syslog(LOG_ERR, "malformed SOA from %s, zone %s: too short\n", inet_ntoa(sin.sin_addr), zp->z_origin);#ifdef DEBUG if (debug) fprintf(ddt, "malformed SOA from %s: too short\n", inet_ntoa(sin.sin_addr));#endif DEBUG (void) close(s); error++; continue; } tmp = buf + sizeof(HEADER); eom = buf + len;#ifdef AUTHEN if ((n = dn_skipname(tmp, eom)) == -1) goto badsoa; tmp += n + ((hp->opcode == AQUERY) ? AQFIXEDSZ : QFIXEDSZ); if ((n = dn_skipname(tmp, eom)) == -1) goto badsoa; tmp += n; if((authen_len = soa_zinfo(&zp_start, tmp, eom)) == -1) goto badsoa; authen_len += tmp - buf;#else AUTHEN if ((n = dn_skipname(tmp, eom)) == -1) goto badsoa; tmp += n + QFIXEDSZ; if ((n = dn_skipname(tmp, eom)) == -1) goto badsoa; tmp += n; if (soa_zinfo(&zp_start, tmp, eom) == -1) goto badsoa;#endif AUTHEN#ifdef AUTHEN if(hp->opcode == AQUERY && defauthentype == AUTH_KRB && defauthenver==ONE) { if(res_rds_krbcred(ONE, "named",zp->z_dname[cnt], &cred, buf, buf + authen_len, eom - (buf + authen_len), zp->z_origin, T_SOA, zp_start.z_class) < RET_OK) {#ifdef DEBUG if (debug) fprintf(ddt, "Authentication error on T_ SOA from %s\n", inet_ntoa(sin.sin_addr));#endif DEBUG (void) close(s); error++; continue; } } else if(netsafe) {#ifdef DEBUG if (debug) fprintf(ddt, "Authenitcation nonexistent on T_ SOA from %s\n", inet_ntoa(sin.sin_addr));#endif DEBUG (void) close(s); error++; continue; }#endif AUTHEN#ifdef ULTRIXFUNC if(zp->z_class == C_ANY) zp->z_class = zp_start.z_class;#endif ULTRIXFUNC if (zp_start.z_serial > serial_no || serial_no == 0) {#ifdef DEBUG if (debug) (void)fprintf(ddt, "need update, serial %d\n", zp_start.z_serial);#endif DEBUG hp = (HEADER *) buf; soacnt = 0; for (;;) { if (soacnt == 0) {#ifdef AUTHEN if(netsafe) { /* switch of auth type */ if ((n = res_mkquery(AQUERY, zp->z_origin, zp->z_class, T_AXFR,(char *)NULL, 0, NULL, buf, bufsize)) < 0) { if (!quiet) syslog(LOG_ERR, "zone %s: res_mkquery T_AXFR failed", zp->z_origin); (void) close(s); (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); return XFER_FAIL; } krbnameptr = res_dotname_head( zp->z_dname[cnt]); if((authen_len = res_mkl_krbcred(ONE, "named", krbnameptr, &cred, buf, buf + n, bufsize - n, zp->z_origin, T_AXFR, zp->z_class)) < RET_OK) { if (!quiet) syslog(LOG_ERR, "zone %s: res_mkl_krbcred T_AXFR failed", zp->z_origin); free(krbnameptr); (void) close(s); (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); return XFER_FAIL; } free(krbnameptr); n += authen_len; } else { if ((n = res_mkquery(QUERY, zp->z_origin, zp->z_class, T_AXFR, (char *)NULL, 0, NULL, buf, bufsize)) < 0) { if (!quiet) syslog(LOG_ERR, "zone %s: res_mkquery T_AXFR failed", zp->z_origin); (void) close(s); (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); return XFER_FAIL; } }#else AUTHEN#ifdef ULTRIXFUNC if ((n = res_mkquery(QUERY, zp->z_origin, C_ANY, T_AXFR, (char *)NULL, 0, NULL, buf, bufsize)) < 0) { if (!quiet) syslog(LOG_ERR, "zone %s: res_mkquery T_AXFR failed", zp->z_origin); (void) close(s); (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); return XFER_FAIL; }#else ULTRIXFUNC if ((n = res_mkquery(QUERY, zp->z_origin, C_IN, T_AXFR, (char *)NULL, 0, NULL, buf, bufsize)) < 0) { if (!quiet) syslog(LOG_ERR, "zone %s: res_mkquery T_AXFR failed", zp->z_origin); (void) close(s); (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); return XFER_FAIL; }#endif ULTRIXFUNC#endif AUTHEN /* * Send length & message for zone transfer */ if (writemsg(s, buf, n) < 0) { (void) close(s); error++;#ifdef DEBUG if (debug >= 2) (void)fprintf(ddt,"writemsg failed\n");#endif break; } } /* * Receive length & response */ cp = buf; l = sizeof(u_short); while (l > 0) { (void) setitimer(ITIMER_REAL, &ival, (struct itimerval *)NULL); errno = 0; if ((n = recv(s, (char *)cp, l, 0)) > 0) { cp += n; l -= n; } else { if (errno == EINTR && !read_interrupted) continue; error++;#ifdef DEBUG if (debug >= 2) (void)fprintf(ddt, "recv failed: n= %d, errno = %d\n", n, errno);#endif#ifdef DEBUG if(errno && debug) (void)fprintf(ddt,"bad recv->%d, errno= %d, read_interrupt=%d\n", n, errno, read_interrupted); else if (debug) (void)fprintf(ddt,"recv timeout occurred, read_interrupt=%d\n", read_interrupted);#endif break; } } (void) setitimer(ITIMER_REAL, &zeroival, (struct itimerval *)NULL); if (error) break; if ((len = htons(*(u_short *)buf)) == 0) break; l = len; cp = buf; eom = buf + len; while (l > 0) { (void) setitimer(ITIMER_REAL, &ival, (struct itimerval *)NULL); errno = 0; if ((n = recv(s, (char *)cp, l, 0)) > 0) { cp += n; l -= n; } else { if (errno == EINTR && !read_interrupted) continue; error++;#ifdef DEBUG if (debug >= 2) (void)fprintf(ddt,"recv failed\n");#endif#ifdef DEBUG if(errno && debug) (void)fprintf(ddt,"bad recv->%d, errno= %d, read_interrupt=%d\n", n, errno, read_interrupted); else if (debug) (void)fprintf(ddt,"recv timeout occurred, read_interrupt=%d\n", read_interrupted);#endif break; } } (void) setitimer(ITIMER_REAL, &zeroival, (struct itimerval *)NULL); if (error) break;#ifdef DEBUG if (debug >= 3) { (void)fprintf(ddt,"len = %d\n", len); fp_query(buf, ddt); } if (fp) fp_query(buf,fp);#endif#ifdef AUTHEN authen = 0;#endif AUTHEN if (len < sizeof(HEADER)) { badrec: error++; if (!quiet) syslog(LOG_ERR, "record too short from %s, zone %s\n", inet_ntoa(sin.sin_addr), zp->z_source);#ifdef DEBUG if (debug) fprintf(ddt, "record too short from %s\n", inet_ntoa(sin.sin_addr));#endif DEBUG break; } cp = buf + sizeof(HEADER);#ifdef AUTHEN if(netsafe && hp->opcode != AQUERY) { syslog(LOG_ERR, "zoneref: res_mkquery non authenticated zone transfer message"); error++;error = 9; break; } if (hp->qdcount) { if ((n = dn_skipname(cp, eom)) == -1 || n + ((hp->opcode == AQUERY) ? AQFIXEDSZ : QFIXEDSZ) >= eom - cp) goto badrec; cp += n + ((hp->opcode == AQUERY) ? AQFIXEDSZ : QFIXEDSZ); } nmp = cp; if((authen_len = dn_expand(hp, eom, cp, name2, sizeof(name2))) < 0) { syslog(LOG_ERR, "zoneref: res_mkquery failed bad dn_expand"); goto badrec; } tmp = cp + authen_len;#else AUTHEN if (hp->qdcount) { if ((n = dn_skipname(cp, eom)) == -1 || n + QFIXEDSZ >= eom - cp) goto badrec; cp += n + QFIXEDSZ; } nmp = cp; if ((n = dn_skipname(cp, eom)) == -1) goto badrec; tmp = cp + n;#endif AUTHEN#ifdef AUTHEN authen = 0; authen_tmp = tmp; GETSHORT(authen_answtype, authen_tmp); GETSHORT(authen_answclass, authen_tmp); authen_tmp += sizeof(u_long); GETSHORT(authen_len, authen_tmp); authen_tmp += authen_len; namptr = name2; if(authen_answtype != T_SOA && authen_answtype!=T_AXFR) res_dotname_rmhead(&namptr); if(netsafe) { krbnameptr = res_dotname_head( zp->z_dname[cnt]); if((authen_len = res_rds_krbcred(ONE, "named", krbnameptr, &cred, hp, authen_tmp, eom - authen_tmp, namptr, authen_answtype, authen_answclass)) < RET_OK) { if (!quiet) syslog(LOG_ERR, "zoneref: res_rds_krbcred failed."); free(krbnameptr); error++; break; } else { authen = 1; free(krbnameptr); n = print_output(buf, bufsize, cp); n += authen_len; } } else { authen = 1; n = print_output(buf, bufsize, cp); }#else AUTHEN n = print_output(buf, bufsize, cp);#endif AUTHEN if (cp + n != eom) {#ifdef DEBUG if (debug) (void)fprintf(ddt, "getzone: print_update failed (%d, %d)\n", cp - buf, n);#endif error++; break; } GETSHORT(n, tmp);#ifdef AUTHEN if (n == T_SOA && authen) {#else AUTHEN if (n == T_SOA) {#endif AUTHEN if (soacnt == 0) { soacnt++; if (dn_expand(buf, buf + 512, nmp, name, sizeof(name)) == -1) goto badsoa; if (eom - tmp <= 2 * sizeof(u_short) + sizeof(u_long)) goto badsoa; tmp += 2 * sizeof(u_short) + sizeof(u_long); if ((n = dn_skipname(tmp, eom)) == -1) goto badsoa; tmp += n; if ((n = dn_skipname(tmp, eom)) == -1) goto badsoa; tmp += n; if (eom - tmp <= sizeof(u_long)) goto badsoa; GETLONG(serial, tmp);#ifdef DEBUG if (debug > 2) (void)fprintf(ddt, "first SOA for %s, serial %d\n", name, serial);#endif DEBUG
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?