Download | Plain Text | No Line Numbers


  1. --- unbound-1.5.10.orig/Makefile.in 2017-11-09 22:58:08.476154201 +0100
  2. +++ unbound-1.5.10/Makefile.in 2017-11-09 23:03:40.370372541 +0100
  3. @@ -112,7 +112,7 @@
  4. validator/autotrust.c validator/val_anchor.c validator/validator.c \
  5. validator/val_kcache.c validator/val_kentry.c validator/val_neg.c \
  6. validator/val_nsec3.c validator/val_nsec.c validator/val_secalgo.c \
  7. -validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c cachedb/cachedb.c $(CHECKLOCK_SRC) \
  8. +validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c cachedb/cachedb.c rewrite/rewrite.c $(CHECKLOCK_SRC) \
  9. $(DNSTAP_SRC)
  10. COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
  11. as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
  12. @@ -123,7 +123,7 @@
  13. random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
  14. slabhash.lo timehist.lo tube.lo winsock_event.lo autotrust.lo val_anchor.lo \
  15. validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
  16. -val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo \
  17. +val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo rewrite.lo \
  18. $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ)
  19. COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
  20. outside_network.lo
  21. @@ -723,7 +723,7 @@
  22. $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
  23. $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/dns64/dns64.h \
  24. $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h \
  25. - $(srcdir)/validator/val_utils.h $(PYTHONMOD_HEADER) $(srcdir)/cachedb/cachedb.h
  26. + $(srcdir)/validator/val_utils.h $(PYTHONMOD_HEADER) $(srcdir)/cachedb/cachedb.h $(srcdir)/rewrite/rewrite.h
  27. outbound_list.lo outbound_list.o: $(srcdir)/services/outbound_list.c config.h \
  28. $(srcdir)/services/outbound_list.h $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
  29. $(srcdir)/util/netevent.h
  30. @@ -768,7 +768,7 @@
  31. $(srcdir)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h \
  32. $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h \
  33. $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h \
  34. - $(PYTHONMOD_HEADER) $(srcdir)/cachedb/cachedb.h
  35. + $(PYTHONMOD_HEADER) $(srcdir)/cachedb/cachedb.h $(srcdir)/rewrite/rewrite.h
  36. locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
  37. log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h
  38. mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
  39. @@ -910,6 +910,12 @@
  40. $(srcdir)/util/rbtree.h $(srcdir)/validator/val_secalgo.h $(srcdir)/iterator/iter_utils.h \
  41. $(srcdir)/iterator/iter_resptype.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \
  42. $(srcdir)/sldns/sbuffer.h
  43. +rewrite.lo rewrite.o: $(srcdir)/rewrite/rewrite.c config.h $(srcdir)/rewrite/rewrite.h $(srcdir)/util/module.h \
  44. + $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
  45. + $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
  46. + $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h $(srcdir)/services/cache/dns.h $(srcdir)/util/config_file.h \
  47. + $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
  48. + $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h
  49. checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
  50. $(srcdir)/testcode/checklocks.h
  51. unitanchor.lo unitanchor.o: $(srcdir)/testcode/unitanchor.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
  52. --- unbound-1.5.10.orig/services/modstack.c 2017-11-09 22:58:08.479154167 +0100
  53. +++ unbound-1.5.10/services/modstack.c 2017-11-09 23:04:36.188736720 +0100
  54. @@ -53,6 +53,7 @@
  55. #ifdef USE_CACHEDB
  56. #include "cachedb/cachedb.h"
  57. #endif
  58. +#include "rewrite/rewrite.h"
  59.  
  60. /** count number of modules (words) in the string */
  61. static int
  62. @@ -129,6 +130,7 @@
  63. #endif
  64. "validator",
  65. "iterator",
  66. + "rewrite",
  67. NULL};
  68. return names;
  69. }
  70. @@ -150,6 +152,7 @@
  71. #endif
  72. &val_get_funcblock,
  73. &iter_get_funcblock,
  74. + &rewrite_get_funcblock,
  75. NULL};
  76. return fb;
  77. }
  78. --- unbound-1.5.10.orig/util/config_file.c 2017-11-09 22:58:08.471154258 +0100
  79. +++ unbound-1.5.10/util/config_file.c 2017-11-09 23:05:30.060123126 +0100
  80. @@ -247,6 +247,7 @@
  81. cfg->ratelimit_below_domain = NULL;
  82. cfg->ratelimit_factor = 10;
  83. cfg->qname_minimisation = 0;
  84. + cfg->rewrite_domain = NULL;
  85. return cfg;
  86. error_exit:
  87. config_delete(cfg);
  88. @@ -797,6 +798,7 @@
  89. else O_LS3(opt, "local-zone-override", local_zone_overrides)
  90. else O_LS3(opt, "access-control-tag-action", acl_tag_actions)
  91. else O_LS3(opt, "access-control-tag-data", acl_tag_datas)
  92. + else O_LS2(opt, "rewrite-domain", rewrite_domain)
  93. /* not here:
  94. * outgoing-permit, outgoing-avoid - have list of ports
  95. * local-zone - zones and nodefault variables
  96. @@ -1063,6 +1065,7 @@
  97. free(cfg->dnstap_version);
  98. config_deldblstrlist(cfg->ratelimit_for_domain);
  99. config_deldblstrlist(cfg->ratelimit_below_domain);
  100. + config_deldblstrlist(cfg->rewrite_domain);
  101. free(cfg);
  102. }
  103.  
  104. --- unbound-1.5.10.orig/util/config_file.h 2017-11-09 22:58:08.472154246 +0100
  105. +++ unbound-1.5.10/util/config_file.h 2017-11-09 23:05:49.042906923 +0100
  106. @@ -396,6 +396,8 @@
  107. int ratelimit_factor;
  108. /** minimise outgoing QNAME and hide original QTYPE if possible */
  109. int qname_minimisation;
  110. + /** from/to-pairs of domains to rewrite */
  111. + struct config_str2list* rewrite_domain;
  112. };
  113.  
  114. /** from cfg username, after daemonise setup performed */
  115. --- unbound-1.5.10.orig/util/configlexer.lex 2017-11-09 22:58:08.474154223 +0100
  116. +++ unbound-1.5.10/util/configlexer.lex 2017-11-09 23:06:18.304573662 +0100
  117. @@ -380,6 +380,7 @@
  118. ratelimit-for-domain{COLON} { YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) }
  119. ratelimit-below-domain{COLON} { YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) }
  120. ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) }
  121. +rewrite-domain{COLON} { YDVAR(2, VAR_REWRITE_DOMAIN) }
  122. <INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
  123.  
  124. /* Quoted strings. Strip leading and ending quotes */
  125. --- unbound-1.5.10.orig/util/configparser.y 2017-11-09 22:58:08.473154235 +0100
  126. +++ unbound-1.5.10/util/configparser.y 2017-11-09 23:08:16.210230970 +0100
  127. @@ -128,6 +128,7 @@
  128. %token VAR_QNAME_MINIMISATION VAR_IP_FREEBIND VAR_DEFINE_TAG VAR_LOCAL_ZONE_TAG
  129. %token VAR_ACCESS_CONTROL_TAG VAR_LOCAL_ZONE_OVERRIDE
  130. %token VAR_ACCESS_CONTROL_TAG_ACTION VAR_ACCESS_CONTROL_TAG_DATA
  131. +%token VAR_REWRITE_DOMAIN
  132.  
  133. %%
  134. toplevelvars: /* empty */ | toplevelvars toplevelvar ;
  135. @@ -199,7 +200,7 @@
  136. server_ip_freebind | server_define_tag | server_local_zone_tag |
  137. server_disable_dnssec_lame_check | server_access_control_tag |
  138. server_local_zone_override | server_access_control_tag_action |
  139. - server_access_control_tag_data
  140. + server_access_control_tag_data | server_rewrite_domain
  141. ;
  142. stubstart: VAR_STUB_ZONE
  143. {
  144. @@ -1497,6 +1498,15 @@
  145. free($2);
  146. }
  147. ;
  148. +server_rewrite_domain: VAR_REWRITE_DOMAIN STRING_ARG STRING_ARG
  149. + {
  150. + OUTYY(("P(server_rewrite_domain:%s %s)\n", $2, $3));
  151. + if(!cfg_str2list_insert(&cfg_parser->cfg->
  152. + rewrite_domain, $2, $3))
  153. + fatal_exit("out of memory adding "
  154. + "rewrite-domain");
  155. + }
  156. + ;
  157. stub_name: VAR_NAME STRING_ARG
  158. {
  159. OUTYY(("P(name:%s)\n", $2));
  160. --- unbound-1.5.10.orig/util/fptr_wlist.c 2017-11-09 22:58:08.474154223 +0100
  161. +++ unbound-1.5.10/util/fptr_wlist.c 2017-11-09 23:09:33.746348119 +0100
  162. @@ -81,6 +81,7 @@
  163. #ifdef USE_CACHEDB
  164. #include "cachedb/cachedb.h"
  165. #endif
  166. +#include "rewrite/rewrite.h"
  167.  
  168. int
  169. fptr_whitelist_comm_point(comm_point_callback_t *fptr)
  170. @@ -321,6 +322,7 @@
  171. #ifdef USE_CACHEDB
  172. else if(fptr == &cachedb_init) return 1;
  173. #endif
  174. + else if(fptr == &rewrite_init) return 1;
  175. return 0;
  176. }
  177.  
  178. @@ -336,6 +338,7 @@
  179. #ifdef USE_CACHEDB
  180. else if(fptr == &cachedb_deinit) return 1;
  181. #endif
  182. + else if(fptr == &rewrite_deinit) return 1;
  183. return 0;
  184. }
  185.  
  186. @@ -352,6 +355,7 @@
  187. #ifdef USE_CACHEDB
  188. else if(fptr == &cachedb_operate) return 1;
  189. #endif
  190. + else if(fptr == &rewrite_operate) return 1;
  191. return 0;
  192. }
  193.  
  194. @@ -368,6 +372,7 @@
  195. #ifdef USE_CACHEDB
  196. else if(fptr == &cachedb_inform_super) return 1;
  197. #endif
  198. + else if(fptr == &rewrite_inform_super) return 1;
  199. return 0;
  200. }
  201.  
  202. @@ -384,6 +389,7 @@
  203. #ifdef USE_CACHEDB
  204. else if(fptr == &cachedb_clear) return 1;
  205. #endif
  206. + else if(fptr == &rewrite_clear) return 1;
  207. return 0;
  208. }
  209.  
  210. @@ -399,6 +405,7 @@
  211. #ifdef USE_CACHEDB
  212. else if(fptr == &cachedb_get_mem) return 1;
  213. #endif
  214. + else if(fptr == &rewrite_get_mem) return 1;
  215. return 0;
  216. }
  217.  
  218. --- /dev/null 1970-01-01 01:00:00.000000000 +0100
  219. +++ unbound-1.5.10/rewrite/rewrite.c 2017-11-09 23:10:03.903004770 +0100
  220. @@ -0,0 +1,446 @@
  221. +/*
  222. + * Copyright (c) 2015, Manuel Mausz. All rights reserved.
  223. + *
  224. + * This software is open source.
  225. + *
  226. + * Redistribution and use in source and binary forms, with or without
  227. + * modification, are permitted provided that the following conditions
  228. + * are met:
  229. + *
  230. + * Redistributions of source code must retain the above copyright notice,
  231. + * this list of conditions and the following disclaimer.
  232. + *
  233. + * Redistributions in binary form must reproduce the above copyright notice,
  234. + * this list of conditions and the following disclaimer in the documentation
  235. + * and/or other materials provided with the distribution.
  236. + *
  237. + * Neither the name of Viagénie nor the names of its contributors may
  238. + * be used to endorse or promote products derived from this software without
  239. + * specific prior written permission.
  240. + *
  241. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  242. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  243. + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  244. + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
  245. + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  246. + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  247. + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  248. + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  249. + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  250. + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  251. + * POSSIBILITY OF SUCH DAMAGE.
  252. + */
  253. +
  254. +#include "config.h"
  255. +#include "rewrite/rewrite.h"
  256. +#include "sldns/str2wire.h"
  257. +#include "services/cache/dns.h"
  258. +#include "util/config_file.h"
  259. +#include "util/fptr_wlist.h"
  260. +#include "util/regional.h"
  261. +#include "util/data/dname.h"
  262. +
  263. +/**
  264. + * This structure contains module configuration information. One instance of
  265. + * this structure exists per instance of the module. Normally there is only one
  266. + * instance of the module.
  267. + */
  268. +struct rewrite_domain {
  269. + uint8_t* dname;
  270. + size_t dname_len;
  271. + int labs;
  272. +};
  273. +
  274. +struct rewrite_env {
  275. + struct rewrite_domain from;
  276. + struct rewrite_domain to;
  277. + struct rewrite_env *next;
  278. +};
  279. +
  280. +enum rewrite_qstate {
  281. + REWRITE_IS_SUBQUERY = 1,
  282. +};
  283. +
  284. +/**
  285. + * This function applies the configuration found in the parsed configuration
  286. + * file \a cfg to this instance of the rewrite module
  287. + *
  288. + * \param rewrite_env Module-specific global parameters.
  289. + * \param cfg Parsed configuration file.
  290. + */
  291. +static int
  292. +rewrite_apply_cfg(struct rewrite_env** rewrite_env, struct config_file* cfg)
  293. +{
  294. + struct rewrite_env** current = rewrite_env;
  295. + struct config_str2list* p;
  296. + *current = NULL;
  297. + for(p = cfg->rewrite_domain; p; p = p->next) {
  298. + struct rewrite_env* entry =
  299. + (struct rewrite_env*)calloc(1, sizeof(struct rewrite_env));
  300. + if (!(entry->from.dname = sldns_str2wire_dname(p->str, &entry->from.dname_len))) {
  301. + log_err("rewrite-domain: cannot parse source field: %s", p->str);
  302. + return 0;
  303. + }
  304. + entry->from.labs = dname_count_labels(entry->from.dname);
  305. + if (!(entry->to.dname = sldns_str2wire_dname(p->str2, &entry->to.dname_len))) {
  306. + log_err("rewrite-domain: cannot parse target field: %s", p->str2);
  307. + return 0;
  308. + }
  309. + entry->to.labs = dname_count_labels(entry->to.dname);
  310. + if (dname_subdomain_c(entry->to.dname, entry->from.dname)) {
  311. + log_err("rewrite-domain: target %s cannot be a sub-domain of source %s",
  312. + p->str, p->str2);
  313. + return 0;
  314. + }
  315. + *current = entry;
  316. + current = &entry->next;
  317. + verbose(VERB_ALGO, "rewrite: added %s => %s", p->str, p->str2);
  318. + }
  319. + return 1;
  320. +}
  321. +
  322. +/**
  323. + * Initializes this instance of the rewrite module.
  324. + *
  325. + * \param env Global state of all module instances.
  326. + * \param id This instance's ID number.
  327. + */
  328. +int
  329. +rewrite_init(struct module_env* env, int id)
  330. +{
  331. + struct rewrite_env* rewrite_env;
  332. + if (!rewrite_apply_cfg(&rewrite_env, env->cfg)) {
  333. + log_err("rewrite: could not apply configuration settings.");
  334. + return 0;
  335. + }
  336. + env->modinfo[id] = (void*)rewrite_env;
  337. + return 1;
  338. +}
  339. +
  340. +/**
  341. + * Deinitializes this instance of the rewrite module.
  342. + *
  343. + * \param env Global state of all module instances.
  344. + * \param id This instance's ID number.
  345. + */
  346. +void
  347. +rewrite_deinit(struct module_env* env, int id)
  348. +{
  349. + if (!env)
  350. + return;
  351. +
  352. + struct rewrite_env* cur = (struct rewrite_env*)env->modinfo[id];
  353. + struct rewrite_env* next;
  354. + while(cur) {
  355. + next = cur->next;
  356. + free(cur->from.dname);
  357. + free(cur->to.dname);
  358. + free(cur);
  359. + cur = next;
  360. + }
  361. +
  362. + env->modinfo[id] = NULL;
  363. +}
  364. +
  365. +static int
  366. +dname_is_subdomain(uint8_t* dname, size_t dname_len,
  367. + struct rewrite_domain* dom)
  368. +{
  369. + return (dname_len > dom->dname_len
  370. + && dname_strict_subdomain(dname, dname_count_labels(dname),
  371. + dom->dname, dom->labs));
  372. +}
  373. +
  374. +
  375. +static struct rewrite_domain
  376. +rewrite_dname(uint8_t* dname, size_t dname_len, struct rewrite_domain* from,
  377. + struct rewrite_domain* to, struct regional *region)
  378. +{
  379. + struct rewrite_domain new = { NULL, 0 };
  380. + size_t sub_len = dname_len - from->dname_len;
  381. + new.dname_len = sub_len + to->dname_len;
  382. +
  383. + if (!(new.dname = regional_alloc(region, new.dname_len)))
  384. + return new;
  385. + memcpy(new.dname, dname, sub_len);
  386. + memcpy(new.dname + sub_len, to->dname, to->dname_len);
  387. +
  388. + char buf[LDNS_MAX_DOMAINLEN+1];
  389. + dname_str((uint8_t*)new.dname, buf);
  390. + verbose(VERB_ALGO, "rewrite: name rewritten to %s", buf);
  391. +
  392. + return new;
  393. +}
  394. +
  395. +/**
  396. + * Handles the "pass" event for a query. This event is received when a new query
  397. + * is received by this module. The query may have been generated internally by
  398. + * another module, in which case we don't want to do any special processing
  399. + * (this is an interesting discussion topic), or it may be brand new, e.g.
  400. + * received over a socket, in which case we do want to do rewrite processing.
  401. + *
  402. + * \param qstate A structure representing the state of the query that has just
  403. + * received the "pass" event.
  404. + * \param id This module's instance ID.
  405. + *
  406. + * \return The new state of the query.
  407. + */
  408. +static enum module_ext_state
  409. +handle_event_pass(struct module_qstate* qstate, int id)
  410. +{
  411. + if (qstate->minfo[id]) {
  412. + /* we're either inside our sub-query ... */
  413. + if ((uintptr_t)qstate->minfo[id] == REWRITE_IS_SUBQUERY)
  414. + return module_wait_module;
  415. + /* ... or called again after the sub-query has finished */
  416. + else
  417. + return module_finished;
  418. + }
  419. +
  420. + struct rewrite_env* rewrite_env;
  421. + for(rewrite_env = (struct rewrite_env*)qstate->env->modinfo[id];
  422. + rewrite_env; rewrite_env = rewrite_env->next) {
  423. + if (dname_is_subdomain(qstate->qinfo.qname, qstate->qinfo.qname_len,
  424. + &rewrite_env->from)) {
  425. + struct rewrite_domain new = rewrite_dname(
  426. + qstate->qinfo.qname, qstate->qinfo.qname_len,
  427. + &rewrite_env->from, &rewrite_env->to,
  428. + qstate->region);
  429. + if (!new.dname)
  430. + return module_error;
  431. +
  432. + qstate->minfo[id] = (void*)rewrite_env;
  433. +
  434. + /* start our sub query */
  435. + struct module_qstate* subq = NULL;
  436. + struct query_info qinfo = qstate->qinfo;
  437. + qinfo.qname = new.dname;
  438. + qinfo.qname_len = new.dname_len;
  439. + fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
  440. + if (!(*qstate->env->attach_sub)(qstate, &qinfo,
  441. + qstate->query_flags, 0, 0, &subq))
  442. + return module_error;
  443. + if (subq) {
  444. + subq->curmod = id;
  445. + subq->ext_state[id] = module_state_initial;
  446. + subq->minfo[id] = (void*)REWRITE_IS_SUBQUERY;
  447. + }
  448. + return module_wait_subquery;
  449. + }
  450. + }
  451. +
  452. + /* otherwise, pass request to next module. */
  453. + return module_wait_module;
  454. +}
  455. +
  456. +/**
  457. + * This is the module's main() function. It gets called each time a query
  458. + * receives an event which we may need to handle. We respond by updating the
  459. + * state of the query.
  460. + *
  461. + * \param qstate Structure containing the state of the query.
  462. + * \param event Event that has just been received.
  463. + * \param id This module's instance ID.
  464. + * \param outbound State of a DNS query on an authoritative server. We never do
  465. + * our own queries ourselves (other modules do it for us), so
  466. + * this is unused.
  467. + */
  468. +void
  469. +rewrite_operate(struct module_qstate* qstate, enum module_ev event, int id,
  470. + struct outbound_entry* outbound)
  471. +{
  472. + (void)outbound;
  473. + switch(event) {
  474. + case module_event_new:
  475. + case module_event_pass:
  476. + qstate->ext_state[id] = handle_event_pass(qstate, id);
  477. + break;
  478. + case module_event_moddone:
  479. + default:
  480. + qstate->ext_state[id] = module_finished;
  481. + break;
  482. + }
  483. +}
  484. +
  485. +/** allocate (special) rrset keys, return 0 on error */
  486. +static int
  487. +repinfo_alloc_rrset_keys(struct reply_info* rep, struct regional* region)
  488. +{
  489. + size_t i;
  490. + for(i = 0; i < rep->rrset_count; i++) {
  491. + rep->rrsets[i] = (struct ub_packed_rrset_key*)regional_alloc_zero(
  492. + region, sizeof(struct ub_packed_rrset_key));
  493. + if (!rep->rrsets[i])
  494. + return 0;
  495. + rep->rrsets[i]->entry.key = rep->rrsets[i];
  496. + rep->rrsets[i]->entry.data = NULL;
  497. + }
  498. + return 1;
  499. +}
  500. +
  501. +/** copy rrsets from replyinfo to dest replyinfo */
  502. +static int
  503. +repinfo_copy_rrsets(struct reply_info* dest, struct reply_info* from,
  504. + struct regional* region, struct rewrite_env* rewrite_env)
  505. +{
  506. + size_t i, s;
  507. + struct packed_rrset_data* fd, *dd;
  508. + struct ub_packed_rrset_key* fk, *dk;
  509. +
  510. + for(i = 0; i < dest->rrset_count; i++) {
  511. + fk = from->rrsets[i];
  512. + dk = dest->rrsets[i];
  513. + fd = (struct packed_rrset_data*)fk->entry.data;
  514. + dk->rk = fk->rk;
  515. + dk->id = fk->id;
  516. +
  517. + if (dname_is_subdomain(fk->rk.dname, fk->rk.dname_len,
  518. + &rewrite_env->to)) {
  519. + struct rewrite_domain new = rewrite_dname(fk->rk.dname,
  520. + fk->rk.dname_len, &rewrite_env->to,
  521. + &rewrite_env->from, region);
  522. + if (!new.dname)
  523. + return 0;
  524. + dk->rk.dname = new.dname;
  525. + dk->rk.dname_len = new.dname_len;
  526. + dk->entry.hash = rrset_key_hash(&dk->rk);
  527. + }
  528. + else {
  529. + dk->entry.hash = fk->entry.hash;
  530. + dk->rk.dname = (uint8_t*)regional_alloc_init(region,
  531. + fk->rk.dname, fk->rk.dname_len);
  532. + if(!dk->rk.dname)
  533. + return 0;
  534. + }
  535. + s = packed_rrset_sizeof(fd);
  536. + dd = (struct packed_rrset_data*)regional_alloc_init(region,
  537. + fd, s);
  538. + if (!dd)
  539. + return 0;
  540. + packed_rrset_ptr_fixup(dd);
  541. + dk->entry.data = (void*)dd;
  542. + }
  543. +
  544. + return 1;
  545. +}
  546. +
  547. +static int
  548. +rewrite_copy_rrsets(struct module_qstate* from, int id,
  549. + struct module_qstate* dest)
  550. +{
  551. + struct rewrite_env* rewrite_env = (struct rewrite_env*)dest->minfo[id];
  552. +
  553. + /* build the actual reply */
  554. + struct reply_info* frep = from->return_msg->rep;
  555. + struct reply_info* drep = construct_reply_info_base(dest->region,
  556. + frep->flags, frep->qdcount, frep->ttl,
  557. + frep->prefetch_ttl, frep->an_numrrsets,
  558. + frep->ns_numrrsets, frep->ar_numrrsets,
  559. + frep->rrset_count, frep->security);
  560. + if (!drep)
  561. + return 0;
  562. +
  563. + /* allocate ub_key structures special or not */
  564. + if (!repinfo_alloc_rrset_keys(drep, dest->region))
  565. + return 0;
  566. +
  567. + /* copy rrsets from replyinfo to dest and replace dname */
  568. + if (!repinfo_copy_rrsets(drep, frep, dest->region, rewrite_env))
  569. + return 0;
  570. +
  571. + if (!dest->return_msg) {
  572. + dest->return_msg = (struct dns_msg*)regional_alloc(
  573. + dest->region, sizeof(struct dns_msg));
  574. + if (!dest->return_msg)
  575. + return 0;
  576. + dest->return_msg->qinfo = dest->qinfo;
  577. + }
  578. + dest->return_msg->rep = drep;
  579. + return 1;
  580. +}
  581. +
  582. +
  583. +/**
  584. + * This function is called when a sub-query finishes to inform the parent query.
  585. + *
  586. + * We issue two kinds of sub-queries: PTR and A.
  587. + *
  588. + * \param qstate State of the sub-query.
  589. + * \param id This module's instance ID.
  590. + * \param super State of the super-query.
  591. + */
  592. +void
  593. +rewrite_inform_super(struct module_qstate* qstate, int id,
  594. + struct module_qstate* super)
  595. +{
  596. + log_query_info(VERB_ALGO, "rewrite: inform_super, sub is",
  597. + &qstate->qinfo);
  598. + log_query_info(VERB_ALGO, "super is", &super->qinfo);
  599. +
  600. + /* sub-query has finished */
  601. + qstate->minfo[id] = NULL;
  602. +
  603. + /* if there is no successful answer, we're done */
  604. + if (qstate->return_rcode != LDNS_RCODE_NOERROR
  605. + || !qstate->return_msg
  606. + || !qstate->return_msg->rep)
  607. + return;
  608. +
  609. + /* copy and rewrite rrsets */
  610. + if (!rewrite_copy_rrsets(qstate, id, super))
  611. + log_err("rewrite: cannot copy rrsets from subquery");
  612. +
  613. + /* store the generated response in cache */
  614. + if (!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
  615. + 0, 0, 0, NULL, super->query_flags))
  616. + log_err("out of memory");
  617. +
  618. +}
  619. +
  620. +/**
  621. + * Clear module-specific data from query state. Since we do not allocate memory,
  622. + * it's just a matter of setting a pointer to NULL.
  623. + *
  624. + * \param qstate Query state.
  625. + * \param id This module's instance ID.
  626. + */
  627. +void
  628. +rewrite_clear(struct module_qstate* qstate, int id)
  629. +{
  630. + qstate->minfo[id] = NULL;
  631. +}
  632. +
  633. +/**
  634. + * Returns the amount of global memory that this module uses, not including
  635. + * per-query data.
  636. + *
  637. + * \param env Module environment.
  638. + * \param id This module's instance ID.
  639. + */
  640. +size_t
  641. +rewrite_get_mem(struct module_env* env, int id)
  642. +{
  643. + size_t mem = 0;
  644. + struct rewrite_env* cur;
  645. + for(cur = (struct rewrite_env*)env->modinfo[id]; cur; cur = cur->next) {
  646. + mem += sizeof(*cur);
  647. + mem += cur->from.dname_len * sizeof(*cur->from.dname);
  648. + mem += cur->to.dname_len * sizeof(*cur->to.dname);
  649. + }
  650. + return mem;
  651. +}
  652. +
  653. +/**
  654. + * The rewrite function block.
  655. + */
  656. +static struct module_func_block rewrite_block = {
  657. + "rewrite",
  658. + &rewrite_init, &rewrite_deinit, &rewrite_operate, &rewrite_inform_super,
  659. + &rewrite_clear, &rewrite_get_mem
  660. +};
  661. +
  662. +struct module_func_block *
  663. +rewrite_get_funcblock()
  664. +{
  665. + return &rewrite_block;
  666. +}
  667. --- /dev/null 1970-01-01 01:00:00.000000000 +0100
  668. +++ unbound-1.5.10/rewrite/rewrite.h 2017-11-09 23:10:03.903004770 +0100
  669. @@ -0,0 +1,63 @@
  670. +/*
  671. + * Copyright (c) 2015, Manuel Mausz. All rights reserved.
  672. + *
  673. + * This software is open source.
  674. + *
  675. + * Redistribution and use in source and binary forms, with or without
  676. + * modification, are permitted provided that the following conditions
  677. + * are met:
  678. + *
  679. + * Redistributions of source code must retain the above copyright notice,
  680. + * this list of conditions and the following disclaimer.
  681. + *
  682. + * Redistributions in binary form must reproduce the above copyright notice,
  683. + * this list of conditions and the following disclaimer in the documentation
  684. + * and/or other materials provided with the distribution.
  685. + *
  686. + * Neither the name of the NLNET LABS nor the names of its contributors may
  687. + * be used to endorse or promote products derived from this software without
  688. + * specific prior written permission.
  689. + *
  690. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  691. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  692. + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  693. + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
  694. + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  695. + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  696. + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  697. + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  698. + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  699. + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  700. + * POSSIBILITY OF SUCH DAMAGE.
  701. + */
  702. +
  703. +#ifndef REWRITE_REWRITE_H
  704. +#define REWRITE_REWRITE_H
  705. +#include "util/module.h"
  706. +
  707. +/**
  708. + * Get the rewrite function block.
  709. + * @return: function block with function pointers to rewrite methods.
  710. + */
  711. +struct module_func_block *rewrite_get_funcblock(void);
  712. +
  713. +/** rewrite init */
  714. +int rewrite_init(struct module_env* env, int id);
  715. +
  716. +/** rewrite deinit */
  717. +void rewrite_deinit(struct module_env* env, int id);
  718. +
  719. +/** rewrite operate on a query */
  720. +void rewrite_operate(struct module_qstate* qstate, enum module_ev event, int id,
  721. + struct outbound_entry* outbound);
  722. +
  723. +void rewrite_inform_super(struct module_qstate* qstate, int id,
  724. + struct module_qstate* super);
  725. +
  726. +/** rewrite cleanup query state */
  727. +void rewrite_clear(struct module_qstate* qstate, int id);
  728. +
  729. +/** rewrite alloc size routine */
  730. +size_t rewrite_get_mem(struct module_env* env, int id);
  731. +
  732. +#endif
  733.