diff --git a/CHANGES b/CHANGES index 7a4fbb008b..1f10729ff4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ + 220. [cleanup] Set the default outgoing port in the view, and + set it in sockaddrs returned from the ADB. + [31-May-2000 explorer] + 219. [bug] Signed truncated messages more correctly follow the respective specs. diff --git a/bin/lwresd/process_gabn.c b/bin/lwresd/process_gabn.c index 2e39e85e67..51098e00ad 100644 --- a/bin/lwresd/process_gabn.c +++ b/bin/lwresd/process_gabn.c @@ -72,7 +72,7 @@ setup_addresses(client_t *client, dns_adbfind_t *find, unsigned int at) { ai = ISC_LIST_HEAD(find->list); while (ai != NULL && client->gabn.naddrs < LWRES_MAX_ADDRS) { - sa = &ai->sockaddr->type.sa; + sa = &ai->sockaddr.type.sa; if (sa->sa_family != af) goto next; @@ -80,13 +80,13 @@ setup_addresses(client_t *client, dns_adbfind_t *find, unsigned int at) { switch (sa->sa_family) { case AF_INET: - sin = &ai->sockaddr->type.sin; + sin = &ai->sockaddr.type.sin; addr->family = LWRES_ADDRTYPE_V4; memcpy(addr->address, &sin->sin_addr, 4); addr->length = 4; break; case AF_INET6: - sin6 = &ai->sockaddr->type.sin6; + sin6 = &ai->sockaddr.type.sin6; addr->family = LWRES_ADDRTYPE_V6; memcpy(addr->address, &sin6->sin6_addr, 16); addr->length = 16; @@ -360,6 +360,7 @@ start_find(client_t *client) { dns_fixedname_name(&client->target_name), dns_rootname, options, 0, dns_fixedname_name(&client->target_name), + client->clientmgr->view->dstport, &client->find); if (client->find != NULL) diff --git a/bin/tests/adb_test.c b/bin/tests/adb_test.c index abcf5a6ede..f5e1469b7d 100644 --- a/bin/tests/adb_test.c +++ b/bin/tests/adb_test.c @@ -176,15 +176,36 @@ create_view(void) { dns_view_setcache(view, cache); dns_cache_detach(&cache); - /* - * Resolver. - * - * XXXRTH hardwired number of tasks. Also, we'll need to - * see if we are dealing with a shared dispatcher in this view. - */ - result = dns_view_createresolver(view, taskmgr, 16, socketmgr, - timermgr, 0, dispatchmgr, NULL, NULL); - check_result(result, "dns_view_createresolver()"); + { + unsigned int attrs; + isc_sockaddr_t any4, any6; + dns_dispatch_t *disp4 = NULL; + dns_dispatch_t *disp6 = NULL; + + isc_sockaddr_any(&any4); + isc_sockaddr_any6(&any6); + + attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP; + RUNTIME_CHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, + taskmgr, &any4, 512, 6, 1024, + 17, 19, attrs, attrs, &disp4) + == ISC_R_SUCCESS); + INSIST(disp4 != NULL); + + attrs = DNS_DISPATCHATTR_IPV6 | DNS_DISPATCHATTR_UDP; + RUNTIME_CHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, + taskmgr, &any6, 512, 6, 1024, + 17, 19, attrs, attrs, &disp6) + == ISC_R_SUCCESS); + INSIST(disp6 != NULL); + + RUNTIME_CHECK(dns_view_createresolver(view, taskmgr, 10, + socketmgr, + timermgr, 0, + dispatchmgr, + disp4, disp6) == + ISC_R_SUCCESS); + } rootdb = NULL; result = dns_rootns_create(mctx, dns_rdataclass_in, NULL, &rootdb); @@ -226,8 +247,8 @@ lookup(char *target) { options |= DNS_ADBFIND_GLUEOK; result = dns_adb_createfind(adb, t2, lookup_callback, client, &client->name, dns_rootname, options, - now, NULL, &client->find); - check_result(result, "dns_adb_lookup()"); + now, NULL, view->dstport, &client->find); + check_result(result, "dns_adb_createfind()"); dns_adb_dumpfind(client->find, stderr); if ((client->find->options & DNS_ADBFIND_WANTEVENT) != 0) @@ -291,7 +312,7 @@ main(int argc, char **argv) { /* * Set the initial debug level. */ - isc_log_setdebuglevel(lctx, 99); + isc_log_setdebuglevel(lctx, 2); create_managers(); diff --git a/lib/dns/adb.c b/lib/dns/adb.c index b4135b328d..26804fdffa 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -276,8 +276,8 @@ static inline dns_adbentry_t *new_adbentry(dns_adb_t *); static inline void free_adbentry(dns_adb_t *, dns_adbentry_t **); static inline dns_adbfind_t *new_adbfind(dns_adb_t *); static inline void free_adbfind(dns_adb_t *, dns_adbfind_t **); -static inline dns_adbaddrinfo_t *new_adbaddrinfo(dns_adb_t *, - dns_adbentry_t *); +static inline dns_adbaddrinfo_t *new_adbaddrinfo(dns_adb_t *, dns_adbentry_t *, + in_port_t); static inline dns_adbfetch_t *new_adbfetch(dns_adb_t *); static inline void free_adbfetch(dns_adb_t *, dns_adbfetch_t **); static inline dns_adbfetch6_t *new_adbfetch6(dns_adb_t *, dns_adbname_t *, @@ -468,11 +468,11 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset, if (rdtype == dns_rdatatype_a) { INSIST(rdata.length == 4); memcpy(&ina.s_addr, rdata.data, 4); - isc_sockaddr_fromin(&sockaddr, &ina, 53); + isc_sockaddr_fromin(&sockaddr, &ina, 0); } else { INSIST(rdata.length == 16); memcpy(in6a.s6_addr, rdata.data, 16); - isc_sockaddr_fromin6(&sockaddr, &in6a, 53); + isc_sockaddr_fromin6(&sockaddr, &in6a, 0); } INSIST(nh == NULL); @@ -571,16 +571,7 @@ import_a6(dns_a6context_t *a6ctx) { goto fail; } - isc_sockaddr_fromin6(&sockaddr, &a6ctx->in6addr, 53); - - if (IN6_IS_ADDR_V4MAPPED(&sockaddr.type.sin6.sin6_addr) - || IN6_IS_ADDR_V4COMPAT(&sockaddr.type.sin6.sin6_addr)) { - isc_buffer_t buffer; - char buff[80]; - - isc_buffer_init(&buffer, buff, sizeof buff); - isc_sockaddr_totext(&sockaddr, &buffer); - } + isc_sockaddr_fromin6(&sockaddr, &a6ctx->in6addr, 0); foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket); if (foundentry == NULL) { @@ -1652,7 +1643,7 @@ free_adbfind(dns_adb_t *adb, dns_adbfind_t **findp) { * if this function returns a valid pointer. */ static inline dns_adbaddrinfo_t * -new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry) { +new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) { dns_adbaddrinfo_t *ai; ai = isc_mempool_get(adb->aimp); @@ -1660,7 +1651,8 @@ new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry) { return (NULL); ai->magic = DNS_ADBADDRINFO_MAGIC; - ai->sockaddr = &entry->sockaddr; + ai->sockaddr = entry->sockaddr; + isc_sockaddr_setport(&ai->sockaddr, port); ai->goodness = entry->goodness; ai->srtt = entry->srtt; ai->flags = entry->flags; @@ -1679,7 +1671,6 @@ free_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) { ai = *ainfo; *ainfo = NULL; - INSIST(ai->sockaddr == NULL); INSIST(ai->entry == NULL); INSIST(!ISC_LINK_LINKED(ai, publink)); @@ -1832,7 +1823,7 @@ copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *zone, find->options |= DNS_ADBFIND_LAMEPRUNED; goto nextv4; } - addrinfo = new_adbaddrinfo(adb, entry); + addrinfo = new_adbaddrinfo(adb, entry, find->port); if (addrinfo == NULL) { find->partial_result |= DNS_ADBFIND_INET; goto out; @@ -1866,7 +1857,7 @@ copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *zone, if (entry_is_bad_for_zone(adb, entry, zone, now)) goto nextv6; - addrinfo = new_adbaddrinfo(adb, entry); + addrinfo = new_adbaddrinfo(adb, entry, find->port); if (addrinfo == NULL) { find->partial_result |= DNS_ADBFIND_INET6; goto out; @@ -2387,7 +2378,7 @@ isc_result_t dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, void *arg, dns_name_t *name, dns_name_t *zone, unsigned int options, isc_stdtime_t now, dns_name_t *target, - dns_adbfind_t **findp) + in_port_t port, dns_adbfind_t **findp) { dns_adbfind_t *find; dns_adbname_t *adbname; @@ -2445,6 +2436,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, if (find == NULL) return (ISC_R_NOMEMORY); + find->port = port; + /* * Remember what types of addresses we are interested in. */ @@ -2723,7 +2716,6 @@ dns_adb_destroyfind(dns_adbfind_t **findp) { ISC_LIST_UNLINK(find->list, ai, publink); entry = ai->entry; ai->entry = NULL; - ai->sockaddr = NULL; INSIST(DNS_ADBENTRY_VALID(entry)); dec_entry_refcnt(adb, entry, ISC_TRUE); free_adbaddrinfo(adb, &ai); @@ -2958,7 +2950,7 @@ dns_adb_dumpfind(dns_adbfind_t *find, FILE *f) { if (ai != NULL) fprintf(f, "\tAddresses:\n"); while (ai != NULL) { - sa = ai->sockaddr; + sa = &ai->sockaddr; switch (sa->type.sa.sa_family) { case AF_INET: tmpp = inet_ntop(AF_INET, &sa->type.sin.sin_addr, @@ -3883,6 +3875,7 @@ dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa, dns_adbentry_t *entry; dns_adbaddrinfo_t *addr; isc_result_t result; + in_port_t port; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(addrp != NULL && *addrp == NULL); @@ -3918,7 +3911,8 @@ dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa, if (entry->avoid_bitstring > 0 && entry->avoid_bitstring < now) entry->avoid_bitstring = 0; - addr = new_adbaddrinfo(adb, entry); + port = isc_sockaddr_getport(sa); + addr = new_adbaddrinfo(adb, entry, port); if (addr != NULL) { inc_entry_refcnt(adb, entry, ISC_FALSE); *addrp = addr; @@ -3961,7 +3955,6 @@ dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) { UNLOCK(&adb->entrylocks[bucket]); addr->entry = NULL; - addr->sockaddr = NULL; free_adbaddrinfo(adb, &addr); if (want_check_exit) { diff --git a/lib/dns/include/dns/adb.h b/lib/dns/include/dns/adb.h index 56642d142e..91042aff78 100644 --- a/lib/dns/include/dns/adb.h +++ b/lib/dns/include/dns/adb.h @@ -75,6 +75,7 @@ #include #include #include +#include #include #include @@ -116,6 +117,7 @@ struct dns_adbfind { /* Private */ isc_mutex_t lock; /* locks all below */ + in_port_t port; int name_bucket; unsigned int flags; dns_adbname_t *adbname; @@ -173,11 +175,11 @@ struct dns_adbfind { struct dns_adbaddrinfo { unsigned int magic; /* private */ - isc_sockaddr_t *sockaddr; /* read only */ - int goodness; - unsigned int srtt; /* microseconds */ - unsigned int flags; - isc_stdtime_t avoid_bitstring; /* 0 == don't */ + isc_sockaddr_t sockaddr; /* [rw] */ + int goodness; /* [rw] */ + unsigned int srtt; /* [rw] microseconds */ + unsigned int flags; /* [rw] */ + isc_stdtime_t avoid_bitstring; /* [rw] 0 == don't */ dns_adbentry_t *entry; /* private */ ISC_LINK(dns_adbaddrinfo_t) publink; }; @@ -294,7 +296,7 @@ isc_result_t dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, void *arg, dns_name_t *name, dns_name_t *zone, unsigned int options, isc_stdtime_t now, dns_name_t *target, - dns_adbfind_t **find); + in_port_t port, dns_adbfind_t **find); /* * Main interface for clients. The adb will look up the name given in * "name" and will build up a list of found addresses, and perhaps start @@ -322,6 +324,10 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, * CNAME'd or DNAME'd to another name), then 'target' will be updated with * the domain name that 'name' is aliased to. * + * All addresses returned will have the sockaddr's port set to 'port.' + * The caller may change them directly in the dns_adbaddrinfo_t since + * they are copies of the internal address only. + * * XXXMLG Document options, especially the flags which control how * events are sent. * diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index f6c5a2ac80..3f28d1c58a 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -104,6 +104,7 @@ struct dns_view { isc_boolean_t provideixfr; dns_ttl_t maxcachettl; dns_ttl_t maxncachettl; + in_port_t dstport; /* * Configurable data for server use only, diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index ba346da316..283f06f540 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -663,15 +663,17 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, query->tcpsocket = NULL; if ((query->options & DNS_FETCHOPT_TCP) != 0) { isc_sockaddr_t any; + int pf; - result = isc_socket_create(res->socketmgr, - isc_sockaddr_pf(addrinfo->sockaddr), + pf = isc_sockaddr_pf(&addrinfo->sockaddr); + + result = isc_socket_create(res->socketmgr, pf, isc_sockettype_tcp, &query->tcpsocket); if (result != ISC_R_SUCCESS) goto cleanup_query; - switch (isc_sockaddr_pf(addrinfo->sockaddr)) { + switch (pf) { case AF_INET: isc_sockaddr_any(&any); break; @@ -691,7 +693,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, * A dispatch will be created once the connect succeeds. */ } else { - switch (isc_sockaddr_pf(addrinfo->sockaddr)) { + switch (isc_sockaddr_pf(&addrinfo->sockaddr)) { case PF_INET: dns_dispatch_attach(res->dispatchv4, &query->dispatch); break; @@ -725,7 +727,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, * XXXRTH Should we attach to the socket? */ result = isc_socket_connect(query->tcpsocket, - addrinfo->sockaddr, task, + &addrinfo->sockaddr, task, resquery_connected, query); if (result != ISC_R_SUCCESS) goto cleanup_query; @@ -805,7 +807,7 @@ resquery_send(resquery_t *query) { * Get a query id from the dispatch. */ result = dns_dispatch_addresponse(query->dispatch, - query->addrinfo->sockaddr, + &query->addrinfo->sockaddr, task, resquery_response, query, @@ -896,7 +898,7 @@ resquery_send(resquery_t *query) { /* * Add TSIG record tailored to the current recipient. */ - isc_netaddr_fromsockaddr(&ipaddr, query->addrinfo->sockaddr); + isc_netaddr_fromsockaddr(&ipaddr, &query->addrinfo->sockaddr); result = dns_peerlist_peerbyaddr(fctx->res->view->peers, &ipaddr, &peer); @@ -958,7 +960,7 @@ resquery_send(resquery_t *query) { * Send the query! */ if ((query->options & DNS_FETCHOPT_TCP) == 0) - address = query->addrinfo->sockaddr; + address = &query->addrinfo->sockaddr; isc_buffer_usedregion(buffer, &r); /* * XXXRTH Make sure we don't send to ourselves! We should probably @@ -1030,7 +1032,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) { attrs = 0; attrs |= DNS_DISPATCHATTR_TCP; attrs |= DNS_DISPATCHATTR_PRIVATE; - if (isc_sockaddr_pf(query->addrinfo->sockaddr) == + if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == AF_INET) attrs |= DNS_DISPATCHATTR_IPV4; else @@ -1166,7 +1168,7 @@ mark_bad(fetchctx_t *fctx) { for (addrinfo = ISC_LIST_HEAD(curr->list); addrinfo != NULL; addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { - if (bad_server(fctx, addrinfo->sockaddr)) + if (bad_server(fctx, &addrinfo->sockaddr)) addrinfo->flags |= FCTX_ADDRINFO_MARK; else all_bad = ISC_FALSE; @@ -1179,7 +1181,7 @@ mark_bad(fetchctx_t *fctx) { for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs); addrinfo != NULL; addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { - if (bad_server(fctx, addrinfo->sockaddr)) + if (bad_server(fctx, &addrinfo->sockaddr)) addrinfo->flags |= FCTX_ADDRINFO_MARK; else all_bad = ISC_FALSE; @@ -1377,7 +1379,7 @@ fctx_getaddresses(fetchctx_t *fctx) { res->buckets[fctx->bucketnum].task, fctx_finddone, fctx, &name, &fctx->domain, options, now, NULL, - &find); + res->view->dstport, &find); if (result != ISC_R_SUCCESS) { if (result == DNS_R_ALIAS) { /* @@ -1488,18 +1490,18 @@ possibly_mark(fetchctx_t *fctx, dns_adbaddrinfo_t *addr) char buf[ISC_NETADDR_FORMATSIZE]; isc_sockaddr_t *sa; - sa = addr->sockaddr; + sa = &addr->sockaddr; if (sa->type.sa.sa_family != AF_INET6) return; if (IN6_IS_ADDR_V4MAPPED(&sa->type.sin6.sin6_addr)) { - isc_netaddr_fromsockaddr(&na, addr->sockaddr); + isc_netaddr_fromsockaddr(&na, sa); isc_netaddr_format(&na, buf, sizeof buf); addr->flags |= FCTX_ADDRINFO_MARK; FCTXTRACE2("Ignoring IPv6 mapped IPV4 address: ", buf); } else if (IN6_IS_ADDR_V4COMPAT(&sa->type.sin6.sin6_addr)) { - isc_netaddr_fromsockaddr(&na, addr->sockaddr); + isc_netaddr_fromsockaddr(&na, sa); isc_netaddr_format(&na, buf, sizeof buf); addr->flags |= FCTX_ADDRINFO_MARK; FCTXTRACE2("Ignoring IPv6 compatibility IPV4 address: ", buf); @@ -3861,7 +3863,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) { * Add this server to the list of bad servers for * this fctx. */ - add_bad(fctx, addrinfo->sockaddr); + add_bad(fctx, &addrinfo->sockaddr); } if (get_nameservers) { diff --git a/lib/dns/view.c b/lib/dns/view.c index a587a1fd77..61b3085841 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -144,6 +144,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->provideixfr = ISC_TRUE; view->maxcachettl = 7 * 24 * 3600; view->maxncachettl = 3 * 3600; + view->dstport = 53; result = dns_peerlist_new(view->mctx, &view->peers); if (result != ISC_R_SUCCESS) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index a395f02bde..86c0405c47 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: zone.c,v 1.133 2000/05/31 21:13:57 gson Exp $ */ +/* $Id: zone.c,v 1.134 2000/06/01 00:30:54 explorer Exp $ */ #include @@ -1652,7 +1652,8 @@ notify_find_address(notify_t *notify) { zone->task, process_adb_event, notify, ¬ify->ns, dns_rootname, - options, 0, NULL, ¬ify->find); + options, 0, NULL, zone->view->dstport, + ¬ify->find); /* Something failed? */ if (result != ISC_R_SUCCESS) { @@ -1772,9 +1773,7 @@ notify_send(notify_t *notify) { for (ai = ISC_LIST_HEAD(notify->find->list); ai != NULL; ai = ISC_LIST_NEXT(ai, publink)) { - dst = *ai->sockaddr; - if (isc_sockaddr_getport(&dst) == 0) - isc_sockaddr_setport(&dst, 53); /* XXX */ + dst = ai->sockaddr; if (notify_isqueued(notify->zone, NULL, &dst)) continue; new = NULL; diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index 5b4376a02d..0915dc765c 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -2347,7 +2347,7 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, set_dev_address(address, sock, dev); if (pktinfo != NULL) { socket_log(sock, NULL, TRACE, - "pktinfo structure provided, ifindex %u", + "pktinfo structure provided, ifindex %u (set to 0)", pktinfo->ipi6_ifindex); dev->attributes |= ISC_SOCKEVENTATTR_PKTINFO;