~/bend-docscommunity

dns.bend fails

raw source on the hub · import bend-kit-dns@0.3.1.1/dns.bend as Dns

DNS A-record lookup over UDP. Source: https://github.com/paymog/bend-kit/tree/main/dns

2 imports
import Base
import 0xb481bb64f1136053b0a6b2c6da6277ab/wire.bend as Wire

Types

type Cur source · line 9 · raw

Data

type RR source · line 12 · raw

Data

type Try source · line 328 · raw

Data

One attempt's outcome: try again, or this answer (None: no address).

Definitions

def u8 source · line 17 · raw

@s:String -> Maybe<&2, Cur>

def u16.lo source · line 24 · raw

@hi:U32 -> @m:Maybe<&2, Cur> -> Maybe<&2, Cur>

def u16.go source · line 31 · raw

@m:Maybe<&2, Cur> -> Maybe<&2, Cur>

def u16 source · line 38 · raw

@s:String -> Maybe<&2, Cur>

def skip.if source · line 41 · raw

@+s:String -> @+n:Nat -> @short:Bool -> Maybe<&2, String>

def skip source · line 48 · raw

@+s:String -> @+n:Nat -> Maybe<&2, String>

def then source · line 51 · raw

@m:Maybe<&2, String> -> @n:Nat -> Maybe<&2, String>

def push16 source · line 58 · raw

@+n:U32 -> @acc:String -> String

def label.ok source · line 64 · raw

@+l:String -> Bool

def label.ascii source · line 68 · raw

@s:String -> Bool

def labels.ok source · line 75 · raw

@xs:List<&2, String> -> Bool

def labels.put source · line 82 · raw

@xs:List<&2, String> -> @acc:String -> String

def query.if source · line 89 · raw

@+id:U32 -> @xs:List<&2, String> -> @ok:Bool -> Maybe<&2, String>

def query.labels source · line 97 · raw

@+id:U32 -> @+xs:List<&2, String> -> Maybe<&2, String>

def strip_dot.if source · line 100 · raw

@+s:String -> @dot:Bool -> String

def strip_dot source · line 107 · raw

@+s:String -> String

def query source · line 111 · raw

@id:U32 -> @name:String -> Maybe<&2, String>

RFC 1035 §4.1: a standard query for the A record of name.

def name.skip source · line 118 · raw

@fuel:Nat -> @s:String -> Maybe<&2, String>

§4.1.4: a name is labels ending in a zero octet, or a two-octet pointer.

def name.then source · line 129 · raw

@m:Maybe<&2, String> -> @n:Nat -> Maybe<&2, String>

def dotted source · line 136 · raw

@s:String -> String

def rr.f source · line 147 · raw

@+r:String -> @+len:U32 -> @a:Bool -> RR

def rr.data source · line 154 · raw

@+r:String -> @+len:U32 -> @a:Bool -> @short:Bool -> RR

def rr.e source · line 161 · raw

@+ty:U32 -> @+cl:U32 -> @m:Maybe<&2, Cur> -> RR

def rr.d source · line 168 · raw

@ty:U32 -> @cl:U32 -> @m:Maybe<&2, String> -> RR

def rr.c source · line 175 · raw

@ty:U32 -> @m:Maybe<&2, Cur> -> RR

def rr.b source · line 182 · raw

@m:Maybe<&2, Cur> -> RR

def rr.a source · line 189 · raw

@m:Maybe<&2, String> -> RR

def rr source · line 197 · raw

@+s:String -> RR

§4.1.3: NAME, TYPE, CLASS, TTL, RDLENGTH, RDATA.

def answers.scan source · line 201 · raw

@fuel:Nat -> @r:RR -> Maybe<&2, String>

fuel = records left. The first A record wins; CNAMEs before it are skipped.

def questions source · line 214 · raw

@fuel:Nat -> @m:Maybe<&2, String> -> Maybe<&2, String>

def body.go source · line 221 · raw

@an:U32 -> @m:Maybe<&2, String> -> Maybe<&2, String>

def body.an source · line 228 · raw

@qd:U32 -> @m:Maybe<&2, Cur> -> Maybe<&2, String>

def body.qd source · line 235 · raw

@m:Maybe<&2, Cur> -> Maybe<&2, String>

def flags.ok source · line 243 · raw

@+f:U32 -> Bool

§4.1.1: QR set, opcode QUERY, not truncated, RCODE 0.

def head.flags.if source · line 246 · raw

@r:String -> @ok:Bool -> Maybe<&2, String>

def head.flags source · line 253 · raw

@m:Maybe<&2, Cur> -> Maybe<&2, String>

def head.id.if source · line 260 · raw

@r:String -> @ok:Bool -> Maybe<&2, String>

def head.id source · line 267 · raw

@id:U32 -> @m:Maybe<&2, Cur> -> Maybe<&2, String>

def answer source · line 275 · raw

@id:U32 -> @msg:String -> Maybe<&2, String>

The IPv4 address the response gives for the query with this id.

def nameservers.add source · line 281 · raw

@+line:String -> @rest:List<&2, String> -> @hit:Bool -> List<&2, String>

def nameservers.go source · line 288 · raw

@xs:List<&2, String> -> List<&2, String>

def nameservers source · line 296 · raw

@conf:String -> List<&2, String>

Every nameserver line, in file order.

def nameserver.first source · line 299 · raw

@xs:List<&2, String> -> Maybe<&2, String>

def nameserver source · line 307 · raw

@conf:String -> Maybe<&2, String>

The first nameserver line of a resolv.conf.

def none source · line 313 · raw

IO(Maybe<&2, String>)

def ipv4.go source · line 316 · raw

@s:String -> Bool

def ipv4 source · line 324 · raw

@+s:String -> Bool

Digits and dots; TCP.connect rejects anything else that is not an address.

def try.pure source · line 332 · raw

@s:Socket -> @t:Try -> IO(Pair(Socket, Try))

def try.from source · line 336 · raw

@s:Socket -> @+ns:String -> @id:U32 -> @hpd:Pair(String, Pair(U32, String)) -> IO(Pair(Socket, Try))

A datagram from anyone but the nameserver's port 53 is ignored (retried).

def try.back source · line 340 · raw

@ns:String -> @id:U32 -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Pair(String, Pair(U32, String))>) -> IO(Pair(Socket, Try))

def try.sent source · line 349 · raw

@ns:String -> @id:U32 -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> IO(Pair(Socket, Try))

§4.2.1 and resolv.conf defaults: 5 s per attempt.

def try.once source · line 359 · raw

@s:Socket -> @+ns:String -> @id:U32 -> @q:String -> IO(Pair(Socket, Try))

def try.close source · line 364 · raw

@s:Socket -> @r:Maybe<&2, String> -> IO(Maybe<&2, String>)

def tries.end source · line 369 · raw

@st:Pair(Socket, Try) -> IO(Maybe<&2, String>)

def tries source · line 378 · raw

@fuel:Nat -> @+ns:String -> @+id:U32 -> @+q:String -> @st:Pair(Socket, Try) -> IO(Maybe<&2, String>)

fuel: attempts left (resolv.conf's default is 2).

def resolve.sock source · line 392 · raw

@ns:String -> @id:U32 -> @q:String -> @r:Result<&1, &1, Pair(U32, String), Socket> -> IO(Maybe<&2, String>)

def resolve.q source · line 399 · raw

@ns:String -> @id:U32 -> @q:Maybe<&2, String> -> IO(Maybe<&2, String>)

def resolve.id source · line 409 · raw

@name:String -> @ns:String -> @r:Result<&1, &1, Pair(U32, String), U32> -> IO(Maybe<&2, String>)

§7.3: a random id makes forged answers harder to land.

def resolve.ns source · line 417 · raw

@name:String -> @ns:Maybe<&2, String> -> IO(Maybe<&2, String>)

def resolve.at source · line 427 · raw

@+host:String -> @ns:String -> IO(Maybe<&2, String>)

Ask one nameserver. Tests use this; resolve reads /etc/resolv.conf.

def conf.text source · line 430 · raw

@r:Result<&1, &1, Pair(U32, String), String> -> String

def resolve.n3 source · line 438 · raw

@+name:String -> @xs:List<&2, String> -> IO(Maybe<&2, String>)

ponytail: 3 nameservers; a longer resolv.conf ignores the rest

def resolve.n2b source · line 445 · raw

@+name:String -> @rest:List<&2, String> -> @ip:Maybe<&2, String> -> IO(Maybe<&2, String>)

def resolve.n2 source · line 452 · raw

@+name:String -> @xs:List<&2, String> -> IO(Maybe<&2, String>)

def resolve.n1b source · line 461 · raw

@+name:String -> @rest:List<&2, String> -> @ip:Maybe<&2, String> -> IO(Maybe<&2, String>)

def resolve.list source · line 468 · raw

@+name:String -> @xs:List<&2, String> -> IO(Maybe<&2, String>)

def resolve.read source · line 477 · raw

@name:String -> @m:Pair(File, Result<&1, &1, Pair(U32, String), String>) -> IO(Maybe<&2, String>)

def resolve.conf source · line 483 · raw

@name:String -> @r:Result<&1, &1, Pair(U32, String), File> -> IO(Maybe<&2, String>)

def resolve.dns source · line 492 · raw

@name:String -> IO(Maybe<&2, String>)

def hosts.pick source · line 498 · raw

@found:Maybe<&2, String> -> @now:Maybe<&2, String> -> Maybe<&2, String>

def hosts.hit source · line 505 · raw

@+ip:String -> @hit:Bool -> Maybe<&2, String>

def hosts.names source · line 512 · raw

@xs:List<&2, String> -> @+name:String -> @+ip:String -> @found:Maybe<&2, String> -> Maybe<&2, String>

def hosts.ip source · line 519 · raw

@+name:String -> @+ip:String -> @ns:List<&2, String> -> @ok:Bool -> Maybe<&2, String>

def hosts.line source · line 526 · raw

@+name:String -> @xs:List<&2, String> -> Maybe<&2, String>

def hosts.sp source · line 533 · raw

@+c:U32 -> @tab:Bool -> U32

def hosts.flat source · line 540 · raw

@s:String -> String

def hosts.scan source · line 547 · raw

@xs:List<&2, String> -> @+name:String -> @found:Maybe<&2, String> -> Maybe<&2, String>

def hosts source · line 555 · raw

@+name:String -> @text:String -> Maybe<&2, String>

First IPv4 address for name in an /etc/hosts file. The name is already lowercase.

def resolve.from source · line 558 · raw

@+name:String -> @m:Maybe<&2, String> -> IO(Maybe<&2, String>)

def resolve.text source · line 565 · raw

@+name:String -> @r:Result<&1, &1, Pair(U32, String), String> -> IO(Maybe<&2, String>)

def resolve.opened source · line 572 · raw

@+name:String -> @m:Pair(File, Result<&1, &1, Pair(U32, String), String>) -> IO(Maybe<&2, String>)

def resolve.hosts source · line 578 · raw

@+name:String -> @r:Result<&1, &1, Pair(U32, String), File> -> IO(Maybe<&2, String>)

def resolve.ask source · line 589 · raw

@+name:String -> IO(Maybe<&2, String>)

An IPv4 address for host: literals as is, localhost (RFC 6761), /etc/hosts, else DNS. ponytail: no AAAA, no TCP retry on TC

def resolve source · line 594 · raw

@+host:String -> IO(Maybe<&2, String>)