+ case GNUNET_DNSPARSER_TYPE_MX:
+ old_off = *off;
+ if (*off + sizeof (uint16_t) > udp_payload_length)
+ return GNUNET_SYSERR;
+ memcpy (&mxpref, &udp_payload[*off], sizeof (uint16_t));
+ (*off) += sizeof (uint16_t);
+ r->data.mx = GNUNET_malloc (sizeof (struct GNUNET_DNSPARSER_MxRecord));
+ r->data.mx->preference = ntohs (mxpref);
+ r->data.mx->mxhost = parse_name (udp_payload,
+ udp_payload_length,
+ off, 0);
+ if (old_off + data_len != *off)
+ return GNUNET_SYSERR;
+ return GNUNET_OK;
+ case GNUNET_DNSPARSER_TYPE_SRV:
+ if ('_' != *r->name)
+ return GNUNET_SYSERR; /* all valid srv names must start with "_" */
+ if (NULL == strstr (r->name, "._"))
+ return GNUNET_SYSERR; /* necessary string from "._$PROTO" not present */
+ old_off = *off;
+ if (*off + sizeof (struct srv_data) > udp_payload_length)
+ return GNUNET_SYSERR;
+ memcpy (&srv, &udp_payload[*off], sizeof (struct srv_data));
+ (*off) += sizeof (struct srv_data);
+ r->data.srv = GNUNET_malloc (sizeof (struct GNUNET_DNSPARSER_SrvRecord));
+ r->data.srv->priority = ntohs (srv.prio);
+ r->data.srv->weight = ntohs (srv.weight);
+ r->data.srv->port = ntohs (srv.port);
+ /* parse 'data.hostname' into components, which are
+ "_$SERVICE._$PROTO.$DOMAIN_NAME" */
+ ndup = GNUNET_strdup (r->name);
+ tok = strtok (ndup, ".");
+ GNUNET_assert (NULL != tok);
+ GNUNET_assert ('_' == *tok);
+ r->data.srv->service = GNUNET_strdup (&tok[1]);
+ tok = strtok (NULL, ".");
+ if ( (NULL == tok) || ('_' != *tok) )
+ {
+ GNUNET_free (r->data.srv);
+ GNUNET_free (ndup);
+ return GNUNET_SYSERR;
+ }
+ r->data.srv->proto = GNUNET_strdup (&tok[1]);
+ tok = strtok (NULL, ".");
+ if (NULL == tok)
+ {
+ GNUNET_free (r->data.srv);
+ GNUNET_free (ndup);
+ return GNUNET_SYSERR;
+ }
+ r->data.srv->domain_name = GNUNET_strdup (tok);
+ GNUNET_free (ndup);
+ r->data.srv->target = parse_name (udp_payload,
+ udp_payload_length,
+ off, 0);
+ if (old_off + data_len != *off)
+ return GNUNET_SYSERR;
+ return GNUNET_OK;
+ default:
+ r->data.raw.data = GNUNET_malloc (data_len);
+ r->data.raw.data_len = data_len;
+ memcpy (r->data.raw.data, &udp_payload[*off], data_len);
+ break;
+ }
+ (*off) += data_len;