ndb/dns: add support for internationalized domain names
This commit is contained in:
parent
94fd92cb69
commit
3720b5ab9c
7 changed files with 370 additions and 60 deletions
|
@ -103,8 +103,7 @@ RR*
|
|||
dblookup(char *name, int class, int type, int auth, int ttl)
|
||||
{
|
||||
int err;
|
||||
char *wild;
|
||||
char buf[256];
|
||||
char buf[Domlen], *wild;
|
||||
RR *rp, *tp;
|
||||
DN *dp, *ndp;
|
||||
|
||||
|
@ -124,7 +123,7 @@ dblookup(char *name, int class, int type, int auth, int ttl)
|
|||
}
|
||||
|
||||
lock(&dblock);
|
||||
dp = dnlookup(name, class, 1);
|
||||
dp = idnlookup(name, class, 1);
|
||||
|
||||
if(opendatabase() < 0)
|
||||
goto out;
|
||||
|
@ -142,7 +141,7 @@ dblookup(char *name, int class, int type, int auth, int ttl)
|
|||
/* walk the domain name trying the wildcard '*' at each position */
|
||||
for(wild = strchr(name, '.'); wild; wild = strchr(wild+1, '.')){
|
||||
snprint(buf, sizeof buf, "*%s", wild);
|
||||
ndp = dnlookup(buf, class, 1);
|
||||
ndp = idnlookup(buf, class, 1);
|
||||
if(ndp->rr)
|
||||
err = 0;
|
||||
if(cfg.cachedb)
|
||||
|
@ -162,7 +161,7 @@ out:
|
|||
* don't call it non-existent if it's not ours
|
||||
* (unless we're a resolver).
|
||||
*/
|
||||
if(err == Rname && (!inmyarea(name) || cfg.resolver))
|
||||
if(err == Rname && (!inmyarea(dp->name) || cfg.resolver))
|
||||
err = Rserver;
|
||||
dp->respcode = err;
|
||||
}
|
||||
|
@ -179,6 +178,18 @@ intval(Ndbtuple *entry, Ndbtuple *pair, char *attr, ulong def)
|
|||
return (t? strtoul(t->val, 0, 10): def);
|
||||
}
|
||||
|
||||
static void
|
||||
mklowcase(char *cp)
|
||||
{
|
||||
Rune r;
|
||||
|
||||
while(*cp != 0){
|
||||
chartorune(&r, cp);
|
||||
r = tolowerrune(r);
|
||||
cp += runetochar(cp, &r);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* lookup an RR in the network database
|
||||
*/
|
||||
|
@ -236,34 +247,43 @@ dblookup1(char *name, int type, int auth, int ttl)
|
|||
case Tixfr:
|
||||
return doaxfr(db, name);
|
||||
default:
|
||||
// dnslog("dnlookup1(%s) bad type", name);
|
||||
// dnslog("dblookup1(%s) bad type", name);
|
||||
return nil;
|
||||
}
|
||||
|
||||
/*
|
||||
* find a matching entry in the database
|
||||
*/
|
||||
t = nil;
|
||||
nstrcpy(dname, name, sizeof dname);
|
||||
free(ndbgetvalue(db, &s, "dom", dname, attr, &t));
|
||||
if(t == nil && strchr(dname, '.') == nil)
|
||||
free(ndbgetvalue(db, &s, "sys", dname, attr, &t));
|
||||
if(t == nil) {
|
||||
char *cp;
|
||||
|
||||
/* try lower case */
|
||||
for(cp = dname; *cp; cp++)
|
||||
if(isupper(*cp)) {
|
||||
for(; *cp; cp++)
|
||||
*cp = tolower(*cp);
|
||||
free(ndbgetvalue(db, &s, "dom", dname, attr, &t));
|
||||
if(t == nil && strchr(dname, '.') == nil)
|
||||
free(ndbgetvalue(db, &s, "sys", dname, attr, &t));
|
||||
break;
|
||||
for(x=0; x<4; x++){
|
||||
switch(x){
|
||||
case 1: /* try unicode */
|
||||
if(idn2utf(name, dname, sizeof dname) == nil){
|
||||
nstrcpy(dname, name, sizeof dname);
|
||||
continue;
|
||||
}
|
||||
if(strcmp(name, dname) == 0)
|
||||
continue;
|
||||
break;
|
||||
case 3: /* try ascii (lower case) */
|
||||
if(utf2idn(name, dname, sizeof dname) == nil)
|
||||
continue;
|
||||
case 2:
|
||||
mklowcase(dname);
|
||||
if(strcmp(name, dname) == 0)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
t = nil;
|
||||
free(ndbgetvalue(db, &s, "dom", dname, attr, &t));
|
||||
if(t == nil && strchr(dname, '.') == nil)
|
||||
free(ndbgetvalue(db, &s, "sys", dname, attr, &t));
|
||||
if(t != nil)
|
||||
break;
|
||||
}
|
||||
|
||||
if(t == nil) {
|
||||
// dnslog("dnlookup1(%s) name not found", name);
|
||||
// dnslog("dblookup1(%s) name not found", name);
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
@ -303,7 +323,7 @@ dblookup1(char *name, int type, int auth, int ttl)
|
|||
if(ttl)
|
||||
rp->ttl = ttl;
|
||||
if(dp == nil)
|
||||
dp = dnlookup(dname, Cin, 1);
|
||||
dp = idnlookup(dname, Cin, 1);
|
||||
rp->owner = dp;
|
||||
*l = rp;
|
||||
l = &rp->next;
|
||||
|
@ -323,14 +343,14 @@ dblookup1(char *name, int type, int auth, int ttl)
|
|||
rp->ttl = ttl;
|
||||
rp->auth = auth;
|
||||
if(dp == nil)
|
||||
dp = dnlookup(dname, Cin, 1);
|
||||
dp = idnlookup(dname, Cin, 1);
|
||||
rp->owner = dp;
|
||||
*l = rp;
|
||||
l = &rp->next;
|
||||
}
|
||||
ndbfree(t);
|
||||
|
||||
// dnslog("dnlookup1(%s) -> %#p", name, list);
|
||||
// dnslog("dblookup1(%s) -> %#p", name, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
@ -406,7 +426,7 @@ cnamerr(Ndbtuple *entry, Ndbtuple *pair)
|
|||
|
||||
USED(entry);
|
||||
rp = rralloc(Tcname);
|
||||
rp->host = dnlookup(pair->val, Cin, 1);
|
||||
rp->host = idnlookup(pair->val, Cin, 1);
|
||||
return rp;
|
||||
}
|
||||
static RR*
|
||||
|
@ -415,7 +435,7 @@ mxrr(Ndbtuple *entry, Ndbtuple *pair)
|
|||
RR *rp;
|
||||
|
||||
rp = rralloc(Tmx);
|
||||
rp->host = dnlookup(pair->val, Cin, 1);
|
||||
rp->host = idnlookup(pair->val, Cin, 1);
|
||||
rp->pref = intval(entry, pair, "pref", 1);
|
||||
return rp;
|
||||
}
|
||||
|
@ -426,7 +446,7 @@ nsrr(Ndbtuple *entry, Ndbtuple *pair)
|
|||
Ndbtuple *t;
|
||||
|
||||
rp = rralloc(Tns);
|
||||
rp->host = dnlookup(pair->val, Cin, 1);
|
||||
rp->host = idnlookup(pair->val, Cin, 1);
|
||||
t = look(entry, pair, "soa");
|
||||
if(t && t->val[0] == 0)
|
||||
rp->local = 1;
|
||||
|
@ -466,7 +486,7 @@ soarr(Ndbtuple *entry, Ndbtuple *pair)
|
|||
ns = look(entry, pair, "ns");
|
||||
if(ns == nil)
|
||||
ns = look(entry, pair, "dom");
|
||||
rp->host = dnlookup(ns->val, Cin, 1);
|
||||
rp->host = idnlookup(ns->val, Cin, 1);
|
||||
|
||||
/* accept all of:
|
||||
* mbox=person
|
||||
|
@ -481,15 +501,15 @@ soarr(Ndbtuple *entry, Ndbtuple *pair)
|
|||
p = strchr(mb->val, '@');
|
||||
if(p != nil)
|
||||
*p = '.';
|
||||
rp->rmb = dnlookup(mb->val, Cin, 1);
|
||||
rp->rmb = idnlookup(mb->val, Cin, 1);
|
||||
} else {
|
||||
snprint(mailbox, sizeof mailbox, "%s.%s",
|
||||
mb->val, ns->val);
|
||||
rp->rmb = dnlookup(mailbox, Cin, 1);
|
||||
rp->rmb = idnlookup(mailbox, Cin, 1);
|
||||
}
|
||||
else {
|
||||
snprint(mailbox, sizeof mailbox, "postmaster.%s", ns->val);
|
||||
rp->rmb = dnlookup(mailbox, Cin, 1);
|
||||
rp->rmb = idnlookup(mailbox, Cin, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -509,7 +529,7 @@ srvrr(Ndbtuple *entry, Ndbtuple *pair)
|
|||
RR *rp;
|
||||
|
||||
rp = rralloc(Tsrv);
|
||||
rp->host = dnlookup(pair->val, Cin, 1);
|
||||
rp->host = idnlookup(pair->val, Cin, 1);
|
||||
rp->srv->pri = intval(entry, pair, "pri", 0);
|
||||
rp->srv->weight = intval(entry, pair, "weight", 0);
|
||||
/* TODO: translate service name to port # */
|
||||
|
@ -624,7 +644,7 @@ dbtuple2cache(Ndbtuple *t)
|
|||
|
||||
for(et = t; et; et = et->entry)
|
||||
if(strcmp(et->attr, "dom") == 0){
|
||||
dp = dnlookup(et->val, Cin, 1);
|
||||
dp = idnlookup(et->val, Cin, 1);
|
||||
|
||||
/* first same line */
|
||||
for(nt = et->line; nt != et; nt = nt->line){
|
||||
|
@ -787,9 +807,6 @@ lookupinfo(char *attr)
|
|||
return t;
|
||||
}
|
||||
|
||||
char *localservers = "local#dns#servers";
|
||||
char *localserverprefix = "local#dns#server";
|
||||
|
||||
/*
|
||||
* return non-zero if this is a bad delegation
|
||||
*/
|
||||
|
@ -892,7 +909,7 @@ addlocaldnsserver(DN *dp, int class, char *ipaddr, int i)
|
|||
|
||||
/* ns record for name server, make up an impossible name */
|
||||
rp = rralloc(Tns);
|
||||
snprint(buf, sizeof buf, "%s%d", localserverprefix, i);
|
||||
snprint(buf, sizeof buf, "local#dns#server%d", i);
|
||||
nsdp = dnlookup(buf, class, 1);
|
||||
rp->host = nsdp;
|
||||
rp->owner = dp; /* e.g., local#dns#servers */
|
||||
|
@ -932,7 +949,7 @@ dnsservers(int class)
|
|||
RR *nsrp;
|
||||
DN *dp;
|
||||
|
||||
dp = dnlookup(localservers, class, 1);
|
||||
dp = dnlookup("local#dns#servers", class, 1);
|
||||
nsrp = rrlookup(dp, Tns, NOneg);
|
||||
if(nsrp != nil)
|
||||
return nsrp;
|
||||
|
|
|
@ -224,6 +224,16 @@ dnlookup(char *name, int class, int enter)
|
|||
return dp;
|
||||
}
|
||||
|
||||
DN*
|
||||
idnlookup(char *name, int class, int enter)
|
||||
{
|
||||
char dom[Domlen];
|
||||
|
||||
if(utf2idn(name, dom, sizeof dom) != nil)
|
||||
name = dom;
|
||||
return dnlookup(name, class, enter);
|
||||
}
|
||||
|
||||
static int
|
||||
rrsame(RR *rr1, RR *rr2)
|
||||
{
|
||||
|
@ -1156,6 +1166,17 @@ dnname(DN *dn)
|
|||
return dn? dn->name: "<null>";
|
||||
}
|
||||
|
||||
static char *
|
||||
idnname(DN *dn, char *buf, int nbuf)
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = dnname(dn);
|
||||
if(idn2utf(name, buf, nbuf) != nil)
|
||||
return buf;
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* print conversion for rr records
|
||||
*/
|
||||
|
@ -1287,7 +1308,7 @@ int
|
|||
rravfmt(Fmt *f)
|
||||
{
|
||||
int rv, quote;
|
||||
char *strp;
|
||||
char buf[Domlen], *strp;
|
||||
Fmt fstr;
|
||||
RR *rp;
|
||||
Server *s;
|
||||
|
@ -1306,34 +1327,37 @@ rravfmt(Fmt *f)
|
|||
if(rp->type == Tptr)
|
||||
fmtprint(&fstr, "ptr=%s", dnname(rp->owner));
|
||||
else
|
||||
fmtprint(&fstr, "dom=%s", dnname(rp->owner));
|
||||
fmtprint(&fstr, "dom=%s", idnname(rp->owner, buf, sizeof(buf)));
|
||||
|
||||
switch(rp->type){
|
||||
case Thinfo:
|
||||
fmtprint(&fstr, " cpu=%s os=%s",
|
||||
dnname(rp->cpu), dnname(rp->os));
|
||||
idnname(rp->cpu, buf, sizeof(buf)),
|
||||
idnname(rp->os, buf, sizeof(buf)));
|
||||
break;
|
||||
case Tcname:
|
||||
fmtprint(&fstr, " cname=%s", dnname(rp->host));
|
||||
fmtprint(&fstr, " cname=%s", idnname(rp->host, buf, sizeof(buf)));
|
||||
break;
|
||||
case Tmb:
|
||||
case Tmd:
|
||||
case Tmf:
|
||||
fmtprint(&fstr, " mbox=%s", dnname(rp->host));
|
||||
fmtprint(&fstr, " mbox=%s", idnname(rp->host, buf, sizeof(buf)));
|
||||
break;
|
||||
case Tns:
|
||||
fmtprint(&fstr, " ns=%s", dnname(rp->host));
|
||||
fmtprint(&fstr, " ns=%s", idnname(rp->host, buf, sizeof(buf)));
|
||||
break;
|
||||
case Tmg:
|
||||
case Tmr:
|
||||
fmtprint(&fstr, " mbox=%s", dnname(rp->mb));
|
||||
fmtprint(&fstr, " mbox=%s", idnname(rp->mb, buf, sizeof(buf)));
|
||||
break;
|
||||
case Tminfo:
|
||||
fmtprint(&fstr, " mbox=%s mbox=%s",
|
||||
dnname(rp->mb), dnname(rp->rmb));
|
||||
idnname(rp->mb, buf, sizeof(buf)),
|
||||
idnname(rp->rmb, buf, sizeof(buf)));
|
||||
break;
|
||||
case Tmx:
|
||||
fmtprint(&fstr, " pref=%lud mx=%s", rp->pref, dnname(rp->host));
|
||||
fmtprint(&fstr, " pref=%lud mx=%s", rp->pref,
|
||||
idnname(rp->host, buf, sizeof(buf)));
|
||||
break;
|
||||
case Ta:
|
||||
case Taaaa:
|
||||
|
@ -1346,7 +1370,8 @@ rravfmt(Fmt *f)
|
|||
soa = rp->soa;
|
||||
fmtprint(&fstr,
|
||||
" ns=%s mbox=%s serial=%lud refresh=%lud retry=%lud expire=%lud ttl=%lud",
|
||||
dnname(rp->host), dnname(rp->rmb),
|
||||
idnname(rp->host, buf, sizeof(buf)),
|
||||
idnname(rp->rmb, buf, sizeof(buf)),
|
||||
(soa? soa->serial: 0),
|
||||
(soa? soa->refresh: 0), (soa? soa->retry: 0),
|
||||
(soa? soa->expire: 0), (soa? soa->minttl: 0));
|
||||
|
@ -1357,7 +1382,7 @@ rravfmt(Fmt *f)
|
|||
srv = rp->srv;
|
||||
fmtprint(&fstr, " pri=%ud weight=%ud port=%ud target=%s",
|
||||
(srv? srv->pri: 0), (srv? srv->weight: 0),
|
||||
rp->port, dnname(rp->host));
|
||||
rp->port, idnname(rp->host, buf, sizeof(buf)));
|
||||
break;
|
||||
case Tnull:
|
||||
if (rp->null == nil)
|
||||
|
@ -1381,7 +1406,8 @@ rravfmt(Fmt *f)
|
|||
break;
|
||||
case Trp:
|
||||
fmtprint(&fstr, " rp=%s txt=%s",
|
||||
dnname(rp->rmb), dnname(rp->rp));
|
||||
idnname(rp->rmb, buf, sizeof(buf)),
|
||||
idnname(rp->rp, buf, sizeof(buf)));
|
||||
break;
|
||||
case Tkey:
|
||||
if (rp->key == nil)
|
||||
|
@ -1399,7 +1425,7 @@ rravfmt(Fmt *f)
|
|||
" type=%d alg=%d labels=%d ttl=%lud exp=%lud incep=%lud tag=%d signer=%s",
|
||||
rp->sig->type, rp->sig->alg, rp->sig->labels,
|
||||
rp->sig->ttl, rp->sig->exp, rp->sig->incep,
|
||||
rp->sig->tag, dnname(rp->sig->signer));
|
||||
rp->sig->tag, idnname(rp->sig->signer, buf, sizeof(buf)));
|
||||
break;
|
||||
case Tcert:
|
||||
if (rp->cert == nil)
|
||||
|
|
|
@ -177,7 +177,7 @@ dnresolve(char *name, int class, int type, Request *req, RR **cn, int depth,
|
|||
* try the name directly
|
||||
*/
|
||||
rp = dnresolve1(name, class, type, req, depth, recurse);
|
||||
if(rp == nil && (dp = dnlookup(name, class, 0)) != nil) {
|
||||
if(rp == nil && (dp = idnlookup(name, class, 0)) != nil) {
|
||||
/*
|
||||
* try it as a canonical name if we weren't told
|
||||
* that the name didn't exist
|
||||
|
@ -348,7 +348,7 @@ issuequery(Query *qp, char *name, int class, int depth, int recurse)
|
|||
}
|
||||
|
||||
/* look for ns in cache */
|
||||
nsdp = dnlookup(cp, class, 0);
|
||||
nsdp = idnlookup(cp, class, 0);
|
||||
nsrp = nil;
|
||||
if(nsdp)
|
||||
nsrp = randomize(rrlookup(nsdp, Tns, NOneg));
|
||||
|
@ -387,7 +387,7 @@ dnresolve1(char *name, int class, int type, Request *req, int depth,
|
|||
if(class != Cin)
|
||||
return nil;
|
||||
|
||||
dp = dnlookup(name, class, 1);
|
||||
dp = idnlookup(name, class, 1);
|
||||
|
||||
/*
|
||||
* Try the cache first
|
||||
|
|
|
@ -453,6 +453,7 @@ void dndump(char*);
|
|||
void dnget(void);
|
||||
void dninit(void);
|
||||
DN* dnlookup(char*, int, int);
|
||||
DN* idnlookup(char*, int, int);
|
||||
void dnptr(uchar*, uchar*, char*, int, int, int);
|
||||
void dnpurge(void);
|
||||
void dnput(void);
|
||||
|
@ -534,4 +535,8 @@ int convDNS2M(DNSmsg*, uchar*, int);
|
|||
/* convM2DNS.c */
|
||||
char* convM2DNS(uchar*, int, DNSmsg*, int*);
|
||||
|
||||
/* idn.c */
|
||||
char* utf2idn(char *, char *, int);
|
||||
char* idn2utf(char *, char *, int);
|
||||
|
||||
#pragma varargck argpos dnslog 1
|
||||
|
|
|
@ -292,7 +292,7 @@ getdnsservers(int class)
|
|||
|
||||
rr = rralloc(Tns);
|
||||
rr->owner = dnlookup("local#dns#servers", class, 1);
|
||||
rr->host = dnlookup(servername, class, 1);
|
||||
rr->host = idnlookup(servername, class, 1);
|
||||
|
||||
return rr;
|
||||
}
|
||||
|
|
262
sys/src/cmd/ndb/idn.c
Normal file
262
sys/src/cmd/ndb/idn.c
Normal file
|
@ -0,0 +1,262 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <ip.h>
|
||||
#include "dns.h"
|
||||
|
||||
enum {
|
||||
base = 36,
|
||||
tmin = 1,
|
||||
tmax = 26,
|
||||
skew = 38,
|
||||
damp = 700,
|
||||
initial_bias = 72,
|
||||
initial_n = 0x80,
|
||||
};
|
||||
|
||||
static uint maxint = ~0;
|
||||
|
||||
static uint
|
||||
decode_digit(uint cp)
|
||||
{
|
||||
if((cp - '0') < 10)
|
||||
return cp - ('0' - 26);
|
||||
if((cp - 'A') < 26)
|
||||
return cp - 'A';
|
||||
if((cp - 'a') < 26)
|
||||
return cp - 'a';
|
||||
return base;
|
||||
}
|
||||
|
||||
static char
|
||||
encode_digit(uint d, int flag)
|
||||
{
|
||||
if(d < 26)
|
||||
return d + (flag ? 'A' : 'a');
|
||||
return d + ('0' - 26);
|
||||
}
|
||||
|
||||
static uint
|
||||
adapt(uint delta, uint numpoints, int firsttime)
|
||||
{
|
||||
uint k;
|
||||
|
||||
delta = firsttime ? delta / damp : delta >> 1;
|
||||
delta += delta / numpoints;
|
||||
for (k = 0; delta > ((base - tmin) * tmax) / 2; k += base)
|
||||
delta /= base - tmin;
|
||||
return k + (base - tmin + 1) * delta / (delta + skew);
|
||||
}
|
||||
|
||||
static int
|
||||
punyencode(uint input_length, Rune input[], uint max_out, char output[])
|
||||
{
|
||||
uint n, delta, h, b, out, bias, j, m, q, k, t;
|
||||
|
||||
n = initial_n;
|
||||
delta = out = 0;
|
||||
bias = initial_bias;
|
||||
|
||||
for (j = 0; j < input_length; ++j) {
|
||||
if ((uint)input[j] < 0x80) {
|
||||
if (max_out - out < 2)
|
||||
return -1;
|
||||
output[out++] = input[j];
|
||||
}
|
||||
}
|
||||
|
||||
h = b = out;
|
||||
|
||||
if (b > 0)
|
||||
output[out++] = '-';
|
||||
|
||||
while (h < input_length) {
|
||||
for (m = maxint, j = 0; j < input_length; ++j) {
|
||||
if (input[j] >= n && input[j] < m)
|
||||
m = input[j];
|
||||
}
|
||||
|
||||
if (m - n > (maxint - delta) / (h + 1))
|
||||
return -1;
|
||||
|
||||
delta += (m - n) * (h + 1);
|
||||
n = m;
|
||||
|
||||
for (j = 0; j < input_length; ++j) {
|
||||
if (input[j] < n) {
|
||||
if (++delta == 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (input[j] == n) {
|
||||
for (q = delta, k = base;; k += base) {
|
||||
if (out >= max_out)
|
||||
return -1;
|
||||
if (k <= bias)
|
||||
t = tmin;
|
||||
else if (k >= bias + tmax)
|
||||
t = tmax;
|
||||
else
|
||||
t = k - bias;
|
||||
if (q < t)
|
||||
break;
|
||||
output[out++] = encode_digit(t + (q - t) % (base - t), 0);
|
||||
q = (q - t) / (base - t);
|
||||
}
|
||||
output[out++] = encode_digit(q, isupperrune(input[j]));
|
||||
bias = adapt(delta, h + 1, h == b);
|
||||
delta = 0;
|
||||
++h;
|
||||
}
|
||||
}
|
||||
|
||||
++delta, ++n;
|
||||
}
|
||||
|
||||
return (int)out;
|
||||
}
|
||||
|
||||
static int
|
||||
punydecode(uint input_length, char input[], uint max_out, Rune output[])
|
||||
{
|
||||
uint n, out, i, bias, b, j, in, oldi, w, k, digit, t;
|
||||
|
||||
n = initial_n;
|
||||
out = i = 0;
|
||||
bias = initial_bias;
|
||||
|
||||
for (b = j = 0; j < input_length; ++j)
|
||||
if (input[j] == '-')
|
||||
b = j;
|
||||
|
||||
if (b > max_out)
|
||||
return -1;
|
||||
|
||||
for (j = 0; j < b; ++j) {
|
||||
if (input[j] & 0x80)
|
||||
return -1;
|
||||
output[out++] = input[j];
|
||||
}
|
||||
|
||||
for (in = b > 0 ? b + 1 : 0; in < input_length; ++out) {
|
||||
for (oldi = i, w = 1, k = base;; k += base) {
|
||||
if (in >= input_length)
|
||||
return -1;
|
||||
digit = decode_digit(input[in++]);
|
||||
if (digit >= base)
|
||||
return -1;
|
||||
if (digit > (maxint - i) / w)
|
||||
return -1;
|
||||
i += digit * w;
|
||||
if (k <= bias)
|
||||
t = tmin;
|
||||
else if (k >= bias + tmax)
|
||||
t = tmax;
|
||||
else
|
||||
t = k - bias;
|
||||
if (digit < t)
|
||||
break;
|
||||
if (w > maxint / (base - t))
|
||||
return -1;
|
||||
w *= (base - t);
|
||||
}
|
||||
|
||||
bias = adapt(i - oldi, out + 1, oldi == 0);
|
||||
|
||||
if (i / (out + 1) > maxint - n)
|
||||
return -1;
|
||||
n += i / (out + 1);
|
||||
i %= (out + 1);
|
||||
|
||||
if (out >= max_out)
|
||||
return -1;
|
||||
|
||||
memmove(output + i + 1, output + i, (out - i) * sizeof *output);
|
||||
if(((uint)input[in-1] - 'A') < 26)
|
||||
output[i++] = toupperrune(n);
|
||||
else
|
||||
output[i++] = tolowerrune(n);
|
||||
}
|
||||
|
||||
return (int)out;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert punycode encoded internationalized
|
||||
* domain name to unicode string
|
||||
*/
|
||||
char*
|
||||
idn2utf(char *name, char *buf, int nbuf)
|
||||
{
|
||||
char *dp, *de, *cp;
|
||||
Rune rb[Domlen], r;
|
||||
int nc, nr, n;
|
||||
|
||||
cp = name;
|
||||
dp = buf;
|
||||
de = dp+nbuf-1;
|
||||
for(;;){
|
||||
nc = nr = 0;
|
||||
while(cp[nc] != 0){
|
||||
n = chartorune(&r, cp+nc);
|
||||
if(r == '.')
|
||||
break;
|
||||
rb[nr++] = r;
|
||||
nc += n;
|
||||
}
|
||||
if(cistrncmp(cp, "xn--", 4) == 0)
|
||||
if((nr = punydecode(nc-4, cp+4, nelem(rb), rb)) < 0)
|
||||
return nil;
|
||||
dp = seprint(dp, de, "%.*S", nr, rb);
|
||||
if(dp >= de)
|
||||
return nil;
|
||||
if(cp[nc] == 0)
|
||||
break;
|
||||
*dp++ = '.';
|
||||
cp += nc+1;
|
||||
}
|
||||
*dp = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert unicode string to punycode
|
||||
* encoded internationalized domain name
|
||||
*/
|
||||
char*
|
||||
utf2idn(char *name, char *buf, int nbuf)
|
||||
{
|
||||
char *dp, *de, *cp;
|
||||
Rune rb[Domlen], r;
|
||||
int nc, nr, n;
|
||||
|
||||
dp = buf;
|
||||
de = dp+nbuf-1;
|
||||
cp = name;
|
||||
for(;;){
|
||||
nc = nr = 0;
|
||||
while(cp[nc] != 0 && nr < nelem(rb)){
|
||||
n = chartorune(&r, cp+nc);
|
||||
if(r == '.')
|
||||
break;
|
||||
rb[nr++] = r;
|
||||
nc += n;
|
||||
}
|
||||
if(nc == nr)
|
||||
dp = seprint(dp, de, "%.*s", nc, cp);
|
||||
else {
|
||||
dp = seprint(dp, de, "xn--");
|
||||
if((n = punyencode(nr, rb, de - dp, dp)) < 0)
|
||||
return nil;
|
||||
dp += n;
|
||||
}
|
||||
if(dp >= de)
|
||||
return nil;
|
||||
if(cp[nc] == 0)
|
||||
break;
|
||||
*dp++ = '.';
|
||||
cp += nc+1;
|
||||
}
|
||||
*dp = 0;
|
||||
return buf;
|
||||
}
|
||||
|
|
@ -17,13 +17,13 @@ TARG = \
|
|||
|
||||
|
||||
DNSOBJ = dns.$O dnudpserver.$O dn.$O dnresolve.$O dblookup.$O dnserver.$O dnnotify.$O\
|
||||
dnarea.$O convM2DNS.$O convDNS2M.$O # lock.$O coherence.$O
|
||||
dnarea.$O convM2DNS.$O convDNS2M.$O idn.$O
|
||||
|
||||
DNSTCPOBJ = dnstcp.$O dn.$O dnresolve.$O dblookup.$O dnserver.$O\
|
||||
dnarea.$O convM2DNS.$O convDNS2M.$O
|
||||
dnarea.$O convM2DNS.$O convDNS2M.$O idn.$O
|
||||
|
||||
DNSDEBUGOBJ = dnsdebug.$O dn.$O dnresolve.$O dblookup.$O dnserver.$O\
|
||||
dnarea.$O convM2DNS.$O convDNS2M.$O
|
||||
dnarea.$O convM2DNS.$O convDNS2M.$O idn.$O
|
||||
|
||||
HFILES = dns.h /$objtype/lib/libndb.a
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue