1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "github.com/brewlin/net-protocol/config"
6
+ "github.com/brewlin/net-protocol/internal/endpoint"
7
+ "github.com/brewlin/net-protocol/pkg/buffer"
8
+ _ "github.com/brewlin/net-protocol/pkg/logging"
9
+ _ "github.com/brewlin/net-protocol/pkg/logging"
10
+ "github.com/brewlin/net-protocol/pkg/waiter"
11
+ "github.com/brewlin/net-protocol/protocol/header"
12
+ "github.com/brewlin/net-protocol/protocol/network/ipv4"
13
+ "github.com/brewlin/net-protocol/protocol/transport/udp"
14
+ "github.com/brewlin/net-protocol/protocol/transport/udp/client"
15
+ "github.com/brewlin/net-protocol/stack"
16
+ "log"
17
+ "strconv"
18
+ "strings"
19
+
20
+ tcpip "github.com/brewlin/net-protocol/protocol"
21
+ )
22
+
23
+ //当前demo作为一个dns代理,接受dns请求并转发后,解析响应做一些操作
24
+ func main () {
25
+ s := endpoint .NewEndpoint ()
26
+
27
+ udploop (s )
28
+
29
+ }
30
+ func udploop (s * stack.Stack ) {
31
+ var wq waiter.Queue
32
+ //新建一个UDP端
33
+ ep , err := s .NewEndpoint (udp .ProtocolNumber , ipv4 .ProtocolNumber , & wq )
34
+ if err != nil {
35
+ log .Fatal (err )
36
+ }
37
+ //绑定本地端口 53是dns默认端口
38
+ if err := ep .Bind (tcpip.FullAddress {1 , config .LocalAddres , 53 }, nil ); err != nil {
39
+ log .Fatal ("@main : bind failed :" , err )
40
+ }
41
+ defer ep .Close ()
42
+ //创建队列 通知 channel
43
+ waitEntry , notifych := waiter .NewChannelEntry (nil )
44
+ wq .EventRegister (& waitEntry , waiter .EventIn )
45
+ defer wq .EventUnregister (& waitEntry )
46
+
47
+ var saddr tcpip.FullAddress
48
+
49
+ for {
50
+ v , _ , err := ep .Read (& saddr )
51
+ if err != nil {
52
+ if err == tcpip .ErrWouldBlock {
53
+ <- notifych
54
+ continue
55
+ }
56
+ fmt .Println (err )
57
+ return
58
+ }
59
+ //接收到代理请求
60
+ h := header .DNS (v )
61
+ fmt .Println ("@main :接收到代理域名:" , string (h [header .DOMAIN :header .DOMAIN + h .GetDomainLen ()- 1 ]))
62
+ go handle_proxy (v ,ep ,saddr )
63
+ }
64
+ }
65
+ //转发代理请求,并解析响应数据
66
+ func handle_proxy (v buffer.View ,ep tcpip.Endpoint ,saddr tcpip.FullAddress ){
67
+ cli := client .NewClient ("8.8.8.8" ,53 )
68
+ cli .Connect ()
69
+ cli .Write (v )
70
+ defer cli .Close ()
71
+
72
+ rsp ,err := cli .Read ()
73
+ if err != nil {
74
+ fmt .Println (err )
75
+ return
76
+ }
77
+ //返回给客户端
78
+ _ , _ , err = ep .Write (tcpip .SlicePayload (rsp ), tcpip.WriteOptions {To : & saddr })
79
+ if err != nil {
80
+ fmt .Println (err )
81
+ }
82
+ p := header .DNS (rsp )
83
+ answer := p .GetAnswer ()
84
+
85
+ for i := 0 ; i < len (* answer ) ; i ++ {
86
+ switch (* answer )[i ].Type {
87
+ case header .A :
88
+ fmt .Println ("dns 目标IP(A):" ,parseAName ((* answer )[i ].RData ))
89
+ case header .CNAME :
90
+ fmt .Println ("dns 目标IP(alias):" ,parseCName ((* answer )[i ].RData ))
91
+ }
92
+ }
93
+ }
94
+ func parseAName (rd []byte ) string {
95
+ res := []string {}
96
+ for _ ,v := range rd {
97
+ res = append (res ,strconv .Itoa (int (v )))
98
+ }
99
+ return strings .Join (res ,"." )
100
+ }
101
+
102
+ func parseCName (rd []byte ) (res string ) {
103
+ for {
104
+ l := int (rd [0 ])
105
+ if l >= len (rd ){
106
+ res += ".com"
107
+ return
108
+ }
109
+ rd = rd [1 :]
110
+ res += string (rd [0 :l ])
111
+ rd = rd [l :]
112
+ if len (rd ) == 0 {
113
+ return
114
+ }
115
+ }
116
+ }
0 commit comments