all repos

scratch @ c33ca6e59056862956a259faa3d453a023a0c3ee

⭐ me doing recreational ~~drugs~~ programming
3 files changed, 115 insertions(+), 43 deletions(-)
dns: ch4
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-04-19 12:31:39 +0300
Authored at: 2026-04-13 16:53:32 +0300
Change ID: vusswnxosqrkynpqvqqrnonpozwwsuxk
Parent: 6fd1757
A dns-server/lookup.go
···
        
        1
        +package main

      
        
        2
        +

      
        
        3
        +import (

      
        
        4
        +	"bytes"

      
        
        5
        +	"fmt"

      
        
        6
        +	"net"

      
        
        7
        +)

      
        
        8
        +

      
        
        9
        +const server = "8.8.8.8:53"

      
        
        10
        +

      
        
        11
        +func Lookup(qname string, qtype QueryType) (Packet, error) {

      
        
        12
        +	conn, _ := net.Dial("udp", server)

      
        
        13
        +	defer conn.Close()

      
        
        14
        +

      
        
        15
        +	p := Packet{}

      
        
        16
        +	p.Header.ID = 6666

      
        
        17
        +	p.Header.RecursionDesired = true

      
        
        18
        +	p.Questions = append(p.Questions, Question{

      
        
        19
        +		Name:  qname,

      
        
        20
        +		Type:  qtype,

      
        
        21
        +		Class: 1, // IN

      
        
        22
        +	})

      
        
        23
        +

      
        
        24
        +	buf := &bytes.Buffer{}

      
        
        25
        +	if err := p.Write(buf); err != nil {

      
        
        26
        +		return Packet{}, fmt.Errorf("failed to write packet: %v", err)

      
        
        27
        +	}

      
        
        28
        +

      
        
        29
        +	if _, err := conn.Write(buf.Bytes()); err != nil {

      
        
        30
        +		fmt.Printf("failed to write to connection: %v", err)

      
        
        31
        +	}

      
        
        32
        +

      
        
        33
        +	res := make([]byte, 512)

      
        
        34
        +	n, err := conn.Read(res)

      
        
        35
        +	if err != nil {

      
        
        36
        +		fmt.Printf("failed to read from connection: %v", err)

      
        
        37
        +	}

      
        
        38
        +

      
        
        39
        +	return ParsePacket(res[:n])

      
        
        40
        +}

      
M dns-server/main.go
···
        1
        1
         package main

      
        2
        2
         

      
        3
        3
         import (

      
        4
        
        -	"bytes"

      
        5
        
        -	_ "embed"

      
        6
        4
         	"fmt"

      
        7
        5
         	"net"

      
        
        6
        +	"os"

      
        8
        7
         )

      
        9
        8
         

      
        10
        9
         func main() {

      
        11
        
        -	qname := "olexsmir.xyz"

      
        12
        
        -	server := "8.8.8.8:53"

      
        13
        
        -

      
        14
        
        -	conn, _ := net.Dial("udp", server)

      
        15
        
        -	defer conn.Close()

      
        16
        
        -

      
        17
        
        -	p := Packet{}

      
        18
        
        -	p.Header.ID = 6666

      
        19
        
        -	p.Header.RecursionDesired = true

      
        20
        
        -	p.Questions = append(p.Questions, Question{

      
        21
        
        -		Name:  qname,

      
        22
        
        -		Type:  AType,

      
        23
        
        -		Class: 1, // IN

      
        24
        
        -	})

      
        25
        
        -

      
        26
        
        -	buf := &bytes.Buffer{}

      
        27
        
        -	if err := p.Write(buf); err != nil {

      
        28
        
        -		fmt.Printf("failed to write packet: %v", err)

      
        29
        
        -	}

      
        30
        
        -

      
        31
        
        -	if _, err := conn.Write(buf.Bytes()); err != nil {

      
        32
        
        -		fmt.Printf("failed to write to connection: %v", err)

      
        33
        
        -	}

      
        34
        
        -

      
        35
        
        -	res := make([]byte, 512)

      
        36
        
        -	n, err := conn.Read(res)

      
        
        10
        +	addr, err := net.ResolveUDPAddr("udp", "0.0.0.0:2053")

      
        37
        11
         	if err != nil {

      
        38
        
        -		fmt.Printf("failed to read from connection: %v", err)

      
        
        12
        +		fmt.Printf("%v\n", err)

      
        39
        13
         	}

      
        40
        14
         

      
        41
        
        -	resPack, err := ParsePacket(res[:n])

      
        
        15
        +	conn, err := net.ListenUDP("udp", addr)

      
        42
        16
         	if err != nil {

      
        43
        
        -		fmt.Printf("failed to parse packet: %v", err)

      
        
        17
        +		fmt.Printf("%v\n", err)

      
        44
        18
         	}

      
        
        19
        +	defer conn.Close()

      
        45
        20
         

      
        46
        
        -	fmt.Printf("%+v\n", resPack.Header)

      
        47
        
        -	for _, q := range resPack.Questions {

      
        48
        
        -		fmt.Printf("%+v\n", q)

      
        49
        
        -	}

      
        50
        
        -	for _, r := range resPack.Answers {

      
        51
        
        -		fmt.Printf("%+v\n", r)

      
        52
        
        -	}

      
        53
        
        -	for _, r := range resPack.Authorities {

      
        54
        
        -		fmt.Printf("%+v\n", r)

      
        55
        
        -	}

      
        56
        
        -	for _, r := range resPack.Resources {

      
        57
        
        -		fmt.Printf("%+v\n", r)

      
        
        21
        +	fmt.Println("Listening on :2053")

      
        
        22
        +	for {

      
        
        23
        +		if err := HandleQuery(conn); err != nil {

      
        
        24
        +			fmt.Fprintf(os.Stderr, "error: %v\n", err)

      
        
        25
        +		}

      
        58
        26
         	}

      
        59
        27
         }

      
A dns-server/server.go
···
        
        1
        +package main

      
        
        2
        +

      
        
        3
        +import (

      
        
        4
        +	"bytes"

      
        
        5
        +	"fmt"

      
        
        6
        +	"net"

      
        
        7
        +)

      
        
        8
        +

      
        
        9
        +func HandleQuery(conn *net.UDPConn) error {

      
        
        10
        +	buf := make([]byte, 512)

      
        
        11
        +	n, src, err := conn.ReadFromUDP(buf)

      
        
        12
        +	if err != nil {

      
        
        13
        +		return err

      
        
        14
        +	}

      
        
        15
        +

      
        
        16
        +	request, err := ParsePacket(buf[:n])

      
        
        17
        +	if err != nil {

      
        
        18
        +		return err

      
        
        19
        +	}

      
        
        20
        +

      
        
        21
        +	response := Packet{

      
        
        22
        +		Header: Header{

      
        
        23
        +			ID:                 request.Header.ID,

      
        
        24
        +			RecursionDesired:   true,

      
        
        25
        +			RecursionAvailable: true,

      
        
        26
        +			Response:           true,

      
        
        27
        +		},

      
        
        28
        +	}

      
        
        29
        +

      
        
        30
        +	if len(request.Questions) == 0 {

      
        
        31
        +		response.Header.Rescode = FORMERR

      
        
        32
        +	} else {

      
        
        33
        +		q := request.Questions[0]

      
        
        34
        +		fmt.Printf("Received query: %+v\n", q)

      
        
        35
        +

      
        
        36
        +		res, rerr := Lookup(q.Name, q.Type)

      
        
        37
        +		if rerr != nil {

      
        
        38
        +			response.Header.Rescode = SERVFAIL

      
        
        39
        +		} else {

      
        
        40
        +			response.Questions = append(response.Questions, q)

      
        
        41
        +			response.Header.Rescode = res.Header.Rescode

      
        
        42
        +			for _, rec := range res.Answers {

      
        
        43
        +				fmt.Printf("Answer: %+v\n", rec)

      
        
        44
        +				response.Answers = append(response.Answers, rec)

      
        
        45
        +			}

      
        
        46
        +			for _, rec := range res.Authorities {

      
        
        47
        +				fmt.Printf("Authority: %+v\n", rec)

      
        
        48
        +				response.Authorities = append(response.Authorities, rec)

      
        
        49
        +			}

      
        
        50
        +			for _, rec := range res.Resources {

      
        
        51
        +				fmt.Printf("Resource: %+v\n", rec)

      
        
        52
        +				response.Resources = append(response.Resources, rec)

      
        
        53
        +			}

      
        
        54
        +		}

      
        
        55
        +	}

      
        
        56
        +

      
        
        57
        +	resBuf := &bytes.Buffer{}

      
        
        58
        +	if err = response.Write(resBuf); err != nil {

      
        
        59
        +		return err

      
        
        60
        +	}

      
        
        61
        +

      
        
        62
        +	_, err = conn.WriteToUDP(resBuf.Bytes(), src)

      
        
        63
        +	return err

      
        
        64
        +}