aboutsummaryrefslogtreecommitdiff
path: root/src/lib/util/dnsparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/util/dnsparser.c')
-rw-r--r--src/lib/util/dnsparser.c130
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 */
153void
154GNUNET_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 */
536struct GNUNET_DNSPARSER_UriRecord *
537GNUNET_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 */
928struct GNUNET_DNSPARSER_UriRecord *
929GNUNET_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 */
1246int
1247GNUNET_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 {