📄 lwdgabn.c
字号:
/* * Save this name away as the current real name. */ client->gabn.realname = (char *) b.base + b.used; client->gabn.realnamelen = client->recv_buffer.used - b.used; return (ISC_R_SUCCESS);}static voidprocess_gabn_finddone(isc_task_t *task, isc_event_t *ev) { ns_lwdclient_t *client = ev->ev_arg; isc_eventtype_t evtype; isc_boolean_t claimed; ns_lwdclient_log(50, "find done for task %p, client %p", task, client); evtype = ev->ev_type; isc_event_free(&ev); /* * No more info to be had? If so, we have all the good stuff * right now, so we can render things. */ claimed = ISC_FALSE; if (evtype == DNS_EVENT_ADBNOMOREADDRESSES) { if (NEED_V4(client)) { client->v4find = client->find; claimed = ISC_TRUE; } if (NEED_V6(client)) { client->v6find = client->find; claimed = ISC_TRUE; } if (client->find != NULL) { if (claimed) client->find = NULL; else dns_adb_destroyfind(&client->find); } generate_reply(client); return; } /* * We probably don't need this find anymore. We're either going to * reissue it, or an error occurred. Either way, we're done with * it. */ if ((client->find != client->v4find) && (client->find != client->v6find)) { dns_adb_destroyfind(&client->find); } else { client->find = NULL; } /* * We have some new information we can gather. Run off and fetch * it. */ if (evtype == DNS_EVENT_ADBMOREADDRESSES) { restart_find(client); return; } /* * An error or other strangeness happened. Drop this query. */ cleanup_gabn(client); ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE);}static voidrestart_find(ns_lwdclient_t *client) { unsigned int options; isc_result_t result; isc_boolean_t claimed; ns_lwdclient_log(50, "starting find for client %p", client); /* * Issue a find for the name contained in the request. We won't * set the bit that says "anything is good enough" -- we want it * all. */ options = 0; options |= DNS_ADBFIND_WANTEVENT; options |= DNS_ADBFIND_RETURNLAME; /* * Set the bits up here to mark that we want this address family * and that we do not currently have a find pending. We will * set that bit again below if it turns out we will get an event. */ if (NEED_V4(client)) options |= DNS_ADBFIND_INET; if (NEED_V6(client)) options |= DNS_ADBFIND_INET6; find_again: INSIST(client->find == NULL); result = dns_adb_createfind(client->clientmgr->view->adb, client->clientmgr->task, process_gabn_finddone, client, dns_fixedname_name(&client->target_name), dns_rootname, options, 0, dns_fixedname_name(&client->target_name), client->clientmgr->view->dstport, &client->find); /* * Did we get an alias? If so, save it and re-issue the query. */ if (result == DNS_R_ALIAS) { ns_lwdclient_log(50, "found alias, restarting query"); dns_adb_destroyfind(&client->find); cleanup_gabn(client); result = add_alias(client); if (result != ISC_R_SUCCESS) { ns_lwdclient_log(50, "out of buffer space adding alias"); ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); return; } goto find_again; } ns_lwdclient_log(50, "find returned %d (%s)", result, isc_result_totext(result)); /* * Did we get an error? */ if (result != ISC_R_SUCCESS) { if (client->find != NULL) dns_adb_destroyfind(&client->find); cleanup_gabn(client); ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); return; } claimed = ISC_FALSE; /* * Did we get our answer to V4 addresses? */ if (NEED_V4(client) && ((client->find->query_pending & DNS_ADBFIND_INET) == 0)) { ns_lwdclient_log(50, "client %p ipv4 satisfied by find %p", client, client->find); claimed = ISC_TRUE; client->v4find = client->find; } /* * Did we get our answer to V6 addresses? */ if (NEED_V6(client) && ((client->find->query_pending & DNS_ADBFIND_INET6) == 0)) { ns_lwdclient_log(50, "client %p ipv6 satisfied by find %p", client, client->find); claimed = ISC_TRUE; client->v6find = client->find; } /* * If we're going to get an event, set our internal pending flag * and return. When we get an event back we'll do the right * thing, basically by calling this function again, perhaps with a * new target name. * * If we have both v4 and v6, and we are still getting an event, * we have a programming error, so die hard. */ if ((client->find->options & DNS_ADBFIND_WANTEVENT) != 0) { ns_lwdclient_log(50, "event will be sent"); INSIST(client->v4find == NULL || client->v6find == NULL); return; } ns_lwdclient_log(50, "no event will be sent"); if (claimed) client->find = NULL; else dns_adb_destroyfind(&client->find); /* * We seem to have everything we asked for, or at least we are * able to respond with things we've learned. */ generate_reply(client);}static isc_result_tstart_find(ns_lwdclient_t *client) { isc_result_t result; /* * Initialize the real name and alias arrays in the reply we're * going to build up. */ init_gabn(client); result = store_realname(client); if (result != ISC_R_SUCCESS) return (result); restart_find(client); return (ISC_R_SUCCESS);}static voidinit_gabn(ns_lwdclient_t *client) { int i; /* * Initialize the real name and alias arrays in the reply we're * going to build up. */ for (i = 0; i < LWRES_MAX_ALIASES; i++) { client->aliases[i] = NULL; client->aliaslen[i] = 0; } for (i = 0; i < LWRES_MAX_ADDRS; i++) { client->addrs[i].family = 0; client->addrs[i].length = 0; memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN); LWRES_LINK_INIT(&client->addrs[i], link); } client->gabn.naliases = 0; client->gabn.naddrs = 0; client->gabn.realname = NULL; client->gabn.aliases = client->aliases; client->gabn.realnamelen = 0; client->gabn.aliaslen = client->aliaslen; LWRES_LIST_INIT(client->gabn.addrs); client->gabn.base = NULL; client->gabn.baselen = 0; /* * Set up the internal buffer to point to the receive region. */ isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH);}/* * When we are called, we can be assured that: * * client->sockaddr contains the address we need to reply to, * * client->pkt contains the packet header data, * * the packet "checks out" overall -- any MD5 hashes or crypto * bits have been verified, * * "b" points to the remaining data after the packet header * was parsed off. * * We are in a the RECVDONE state. * * From this state we will enter the SEND state if we happen to have * everything we need or we need to return an error packet, or to the * FINDWAIT state if we need to look things up. */voidns_lwdclient_processgabn(ns_lwdclient_t *client, lwres_buffer_t *b) { isc_result_t result; lwres_gabnrequest_t *req; ns_lwdclientmgr_t *cm; isc_buffer_t namebuf; REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); cm = client->clientmgr; req = NULL; result = lwres_gabnrequest_parse(client->clientmgr->lwctx, b, &client->pkt, &req); if (result != LWRES_R_SUCCESS) goto out; if (req->name == NULL) goto out; isc_buffer_init(&namebuf, req->name, req->namelen); isc_buffer_add(&namebuf, req->namelen); dns_fixedname_init(&client->target_name); dns_fixedname_init(&client->query_name); result = dns_name_fromtext(dns_fixedname_name(&client->query_name), &namebuf, NULL, ISC_FALSE, NULL); if (result != ISC_R_SUCCESS) goto out; ns_lwsearchctx_init(&client->searchctx, cm->listener->manager->search, dns_fixedname_name(&client->query_name), cm->listener->manager->ndots); ns_lwsearchctx_first(&client->searchctx); client->find_wanted = req->addrtypes; ns_lwdclient_log(50, "client %p looking for addrtypes %08x", client, client->find_wanted); /* * We no longer need to keep this around. */ lwres_gabnrequest_free(client->clientmgr->lwctx, &req); /* * Start the find. */ result = start_find(client); if (result != ISC_R_SUCCESS) goto out; return; /* * We're screwed. Return an error packet to our caller. */ out: if (req != NULL) lwres_gabnrequest_free(client->clientmgr->lwctx, &req); ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -