#include "ipalloc.h" #include "stralloc.h" #include "dns.h" #include "byte.h" #include "uint16.h" #include "curveresolve.h" #include "error.h" #include "dns_mxip.h" static stralloc out = {0}; static stralloc out2 = {0}; static stralloc host = {0}; static stralloc key = {0}; static stralloc ext = {0}; static char *q = 0; static void sort(ipalloc *ip){ long long i, j; struct ip_mx ix; if (ip->len < 2) return; for (i = ip->len - 1; i > 0; --i) { for (j = 1; j <= i; ++j) { if (ip->ix[j-1].pref > ip->ix[j].pref) { byte_copy(&ix, sizeof(struct ip_mx), &ip->ix[j-1]); byte_copy(&ip->ix[j-1], sizeof(struct ip_mx), &ip->ix[j]); byte_copy(&ip->ix[j], sizeof(struct ip_mx), &ix); } } } } int dns_mxip(ipalloc *ia, stralloc *fqdn, int flagrelay) { long long i, j, k; uint16 pref; struct ip_mx ix; int temperr = 0; if (!ipalloc_readyplus(ia,0)) return -1; ia->len = 0; if (!stralloc_copys(&out, "")) return -1; if (!flagrelay) if (dns_mx(&out,fqdn) == -1) return -1; if (!out.len) { if (!stralloc_copyb(&out,"\0\0",2)) return -1; if (!dns_domain_fromdot(&q,fqdn->s, fqdn->len)) return -1; if (!dns_domain_todot_cat(&out,q)) return -1; dns_domain_free(&q); if (!stralloc_0(&out)) return -1; } i = 0; while (i + 2 < out.len) { byte_zero(&ix, sizeof(struct ip_mx)); j = byte_chr(out.s + i + 2,out.len - i - 2,0); uint16_unpack_big(out.s + i, &pref); if (!stralloc_copyb(&host, out.s + i + 2,j)) return -1; if (curveresolve(&out2, &key, &ext, &host, 's') == -1) { if (errno == error_nomem) return -1; temperr = 1; i += j + 3; continue; } ix.pref = pref; if (key.len == 64 && ext.len == 32) { if (!stralloc_0(&key)) return -1; if (!stralloc_0(&ext)) return -1; /* XXX */ ix.key = key.s; key.s = 0; key.len = 0; key.a = 0; ix.ext = ext.s; ext.s = 0; ext.len = 0; ext.a = 0; /* ix.name = host.s; host.s = 0; host.len = 0; host.a = 0; */ ix.haskey = 1; } if (!stralloc_0(&host)) return -1; ix.name = host.s; host.s = 0; host.len = 0; host.a = 0; for (k = 0;k + 4 <= out2.len;k += 4) { byte_copy(ix.ip, 4, out2.s + k); if (!ipalloc_append(ia,&ix)) return -1; } i += j + 3; } if (temperr && ia->len <= 0) return -1; sort(ia); return 0; }