diff options
Diffstat (limited to 'src/lib/util/dnsparser.c')
-rw-r--r-- | src/lib/util/dnsparser.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/src/lib/util/dnsparser.c b/src/lib/util/dnsparser.c index dab38def7..eb2d8a93b 100644 --- a/src/lib/util/dnsparser.c +++ b/src/lib/util/dnsparser.c | |||
@@ -146,6 +146,21 @@ GNUNET_DNSPARSER_free_srv (struct GNUNET_DNSPARSER_SrvRecord *srv) | |||
146 | 146 | ||
147 | 147 | ||
148 | /** | 148 | /** |
149 | * Free URI information record. | ||
150 | * | ||
151 | * @param uri record to free | ||
152 | */ | ||
153 | void | ||
154 | GNUNET_DNSPARSER_free_uri (struct GNUNET_DNSPARSER_UriRecord *uri) | ||
155 | { | ||
156 | if (NULL == uri) | ||
157 | return; | ||
158 | GNUNET_free (uri->target); | ||
159 | GNUNET_free (uri); | ||
160 | } | ||
161 | |||
162 | |||
163 | /** | ||
149 | * Free MX information record. | 164 | * Free MX information record. |
150 | * | 165 | * |
151 | * @param mx record to free | 166 | * @param mx record to free |
@@ -183,6 +198,10 @@ GNUNET_DNSPARSER_free_record (struct GNUNET_DNSPARSER_Record *r) | |||
183 | GNUNET_DNSPARSER_free_srv (r->data.srv); | 198 | GNUNET_DNSPARSER_free_srv (r->data.srv); |
184 | break; | 199 | break; |
185 | 200 | ||
201 | case GNUNET_DNSPARSER_TYPE_URI: | ||
202 | GNUNET_DNSPARSER_free_uri (r->data.uri); | ||
203 | break; | ||
204 | |||
186 | case GNUNET_DNSPARSER_TYPE_CERT: | 205 | case GNUNET_DNSPARSER_TYPE_CERT: |
187 | GNUNET_DNSPARSER_free_cert (r->data.cert); | 206 | GNUNET_DNSPARSER_free_cert (r->data.cert); |
188 | break; | 207 | break; |
@@ -506,6 +525,46 @@ GNUNET_DNSPARSER_parse_srv (const char *udp_payload, | |||
506 | 525 | ||
507 | 526 | ||
508 | /** | 527 | /** |
528 | * Parse a DNS URI record. | ||
529 | * | ||
530 | * @param udp_payload reference to UDP packet | ||
531 | * @param udp_payload_length length of @a udp_payload | ||
532 | * @param off pointer to the offset of the query to parse in the URI record (to be | ||
533 | * incremented by the size of the record), unchanged on error | ||
534 | * @return the parsed URI record, NULL on error | ||
535 | */ | ||
536 | struct GNUNET_DNSPARSER_UriRecord * | ||
537 | GNUNET_DNSPARSER_parse_uri (const char *udp_payload, | ||
538 | size_t udp_payload_length, | ||
539 | size_t *off) | ||
540 | { | ||
541 | struct GNUNET_DNSPARSER_UriRecord *uri; | ||
542 | struct GNUNET_TUN_DnsUriRecord uri_bin; | ||
543 | size_t old_off; | ||
544 | |||
545 | old_off = *off; | ||
546 | if (*off + sizeof(struct GNUNET_TUN_DnsUriRecord) > udp_payload_length) | ||
547 | return NULL; | ||
548 | GNUNET_memcpy (&uri_bin, | ||
549 | &udp_payload[*off], | ||
550 | sizeof(struct GNUNET_TUN_DnsUriRecord)); | ||
551 | (*off) += sizeof(struct GNUNET_TUN_DnsUriRecord); | ||
552 | uri = GNUNET_new (struct GNUNET_DNSPARSER_UriRecord); | ||
553 | uri->priority = ntohs (uri_bin.prio); | ||
554 | uri->weight = ntohs (uri_bin.weight); | ||
555 | GNUNET_asprintf(&(uri->target), "%.*s", udp_payload_length - sizeof(struct GNUNET_TUN_DnsUriRecord), &udp_payload[*off]); | ||
556 | (*off) += sizeof(uri->target) + 1; | ||
557 | if (NULL == uri->target) // || GNUNET_STRINGS_parse_uri(uri->target, NULL, NULL) == GNUNET_NO) | ||
558 | { | ||
559 | GNUNET_DNSPARSER_free_uri (uri); | ||
560 | *off = old_off; | ||
561 | return NULL; | ||
562 | } | ||
563 | return uri; | ||
564 | } | ||
565 | |||
566 | |||
567 | /** | ||
509 | * Parse a DNS CERT record. | 568 | * Parse a DNS CERT record. |
510 | * | 569 | * |
511 | * @param udp_payload reference to UDP packet | 570 | * @param udp_payload reference to UDP packet |
@@ -633,6 +692,16 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload, | |||
633 | } | 692 | } |
634 | return GNUNET_OK; | 693 | return GNUNET_OK; |
635 | 694 | ||
695 | case GNUNET_DNSPARSER_TYPE_URI: | ||
696 | r->data.uri = | ||
697 | GNUNET_DNSPARSER_parse_uri (udp_payload, udp_payload_length, off); | ||
698 | if ((NULL == r->data.uri) || (old_off + data_len != *off)) | ||
699 | { | ||
700 | GNUNET_break_op (0); | ||
701 | return GNUNET_SYSERR; | ||
702 | } | ||
703 | return GNUNET_OK; | ||
704 | |||
636 | default: | 705 | default: |
637 | r->data.raw.data = GNUNET_malloc (data_len); | 706 | r->data.raw.data = GNUNET_malloc (data_len); |
638 | r->data.raw.data_len = data_len; | 707 | r->data.raw.data_len = data_len; |
@@ -768,6 +837,11 @@ GNUNET_DNSPARSER_duplicate_record (const struct GNUNET_DNSPARSER_Record *r) | |||
768 | break; | 837 | break; |
769 | } | 838 | } |
770 | 839 | ||
840 | case GNUNET_DNSPARSER_TYPE_URI: { | ||
841 | dup->data.uri = GNUNET_DNSPARSER_duplicate_uri_record (r->data.uri); | ||
842 | break; | ||
843 | } | ||
844 | |||
771 | default: { | 845 | default: { |
772 | dup->data.raw.data = GNUNET_memdup (r->data.raw.data, | 846 | dup->data.raw.data = GNUNET_memdup (r->data.raw.data, |
773 | r->data.raw.data_len); | 847 | r->data.raw.data_len); |
@@ -846,6 +920,23 @@ GNUNET_DNSPARSER_duplicate_srv_record ( | |||
846 | 920 | ||
847 | 921 | ||
848 | /** | 922 | /** |
923 | * Duplicate (deep-copy) the given DNS record | ||
924 | * | ||
925 | * @param r the record | ||
926 | * @return the newly allocated record | ||
927 | */ | ||
928 | struct GNUNET_DNSPARSER_UriRecord * | ||
929 | GNUNET_DNSPARSER_duplicate_uri_record ( | ||
930 | const struct GNUNET_DNSPARSER_UriRecord *r) | ||
931 | { | ||
932 | struct GNUNET_DNSPARSER_UriRecord *dup = GNUNET_memdup (r, sizeof(*r)); | ||
933 | |||
934 | dup->target = GNUNET_strdup (r->target); | ||
935 | return dup; | ||
936 | } | ||
937 | |||
938 | |||
939 | /** | ||
849 | * Free memory taken by a packet. | 940 | * Free memory taken by a packet. |
850 | * | 941 | * |
851 | * @param p packet to free | 942 | * @param p packet to free |
@@ -1141,6 +1232,40 @@ GNUNET_DNSPARSER_builder_add_srv (char *dst, | |||
1141 | 1232 | ||
1142 | 1233 | ||
1143 | /** | 1234 | /** |
1235 | * Add an URI record to the UDP packet at the given location. | ||
1236 | * | ||
1237 | * @param dst where to write the URI record | ||
1238 | * @param dst_len number of bytes in @a dst | ||
1239 | * @param off pointer to offset where to write the URI information (increment by bytes used) | ||
1240 | * can also change if there was an error | ||
1241 | * @param uri URI information to write | ||
1242 | * @return #GNUNET_SYSERR if @a uri is invalid | ||
1243 | * #GNUNET_NO if @a uri did not fit | ||
1244 | * #GNUNET_OK if @a uri was added to @a dst | ||
1245 | */ | ||
1246 | int | ||
1247 | GNUNET_DNSPARSER_builder_add_uri (char *dst, | ||
1248 | size_t dst_len, | ||
1249 | size_t *off, | ||
1250 | const struct GNUNET_DNSPARSER_UriRecord *uri) | ||
1251 | { | ||
1252 | struct GNUNET_TUN_DnsUriRecord sd; | ||
1253 | int ret; | ||
1254 | |||
1255 | if (*off + sizeof(struct GNUNET_TUN_DnsUriRecord) > dst_len) | ||
1256 | return GNUNET_NO; | ||
1257 | sd.prio = htons (uri->priority); | ||
1258 | sd.weight = htons (uri->weight); | ||
1259 | GNUNET_memcpy (&dst[*off], &sd, sizeof(sd)); | ||
1260 | (*off) += sizeof(sd); | ||
1261 | GNUNET_memcpy(&dst[*off], uri->target, sizeof(uri->target)); | ||
1262 | (*off) += sizeof(uri->target); | ||
1263 | dst[*off++] = '\0'; | ||
1264 | return GNUNET_OK; | ||
1265 | } | ||
1266 | |||
1267 | |||
1268 | /** | ||
1144 | * Add a DNS record to the UDP packet at the given location. | 1269 | * Add a DNS record to the UDP packet at the given location. |
1145 | * | 1270 | * |
1146 | * @param dst where to write the query | 1271 | * @param dst where to write the query |
@@ -1205,6 +1330,11 @@ add_record (char *dst, | |||
1205 | GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &pos, record->data.srv); | 1330 | GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &pos, record->data.srv); |
1206 | break; | 1331 | break; |
1207 | 1332 | ||
1333 | case GNUNET_DNSPARSER_TYPE_URI: | ||
1334 | ret = | ||
1335 | GNUNET_DNSPARSER_builder_add_uri (dst, dst_len, &pos, record->data.uri); | ||
1336 | break; | ||
1337 | |||
1208 | default: | 1338 | default: |
1209 | if (pos + record->data.raw.data_len > dst_len) | 1339 | if (pos + record->data.raw.data_len > dst_len) |
1210 | { | 1340 | { |