@@ -2,6 +2,7 @@ package main
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"flag"
6
7
"fmt"
7
8
"net"
@@ -40,6 +41,31 @@ func (o *options) run(ctx context.Context) error {
40
41
}
41
42
}
42
43
44
+ func writeACK (c net.Conn , ack xnet.Acknowledgement ) error {
45
+ data := ack .Marshal ()
46
+ _ , err := c .Write (data )
47
+ return err
48
+ }
49
+
50
+ func ackCodeFromErr (err error ) xnet.AckCode {
51
+ var dnsErr * net.DNSError
52
+ if errors .As (err , & dnsErr ) {
53
+ if dnsErr .IsNotFound {
54
+ return xnet .AckCodeNoSuchHost
55
+ }
56
+ if dnsErr .IsTimeout {
57
+ return xnet .AckCodeResolveTimeout
58
+ }
59
+ }
60
+
61
+ var opErr * net.OpError
62
+ if errors .As (err , & opErr ) && opErr .Timeout () {
63
+ return xnet .AckCodeConnectTimeout
64
+ }
65
+
66
+ return xnet .AckCodeUnknownError
67
+ }
68
+
43
69
func handleConn (ctx context.Context , c * net.TCPConn , dialer * net.Dialer ) {
44
70
defer c .Close ()
45
71
@@ -57,6 +83,16 @@ func handleConn(ctx context.Context, c *net.TCPConn, dialer *net.Dialer) {
57
83
upstreamConn , err := dialer .DialContext (ctx , constants .ProtocolTCP , dstAddr )
58
84
if err != nil {
59
85
klog .ErrorS (err , "Fail to create tcp connection" , constants .LogFieldRequestID , hdr .RequestID , constants .LogFieldDestAddr , dstAddr )
86
+ _ = writeACK (c , xnet.Acknowledgement {
87
+ Code : ackCodeFromErr (err ),
88
+ })
89
+ return
90
+ }
91
+ err = writeACK (c , xnet.Acknowledgement {
92
+ Code : xnet .AckCodeOK ,
93
+ })
94
+ if err != nil {
95
+ klog .ErrorS (err , "Fail to write ack" , constants .LogFieldRequestID , hdr .RequestID )
60
96
return
61
97
}
62
98
klog .InfoS ("Start proxy tcp request" , constants .LogFieldRequestID , hdr .RequestID , constants .LogFieldDestAddr , dstAddr )
@@ -66,6 +102,16 @@ func handleConn(ctx context.Context, c *net.TCPConn, dialer *net.Dialer) {
66
102
upstreamConn , err := dialer .DialContext (ctx , constants .ProtocolUDP , dstAddr )
67
103
if err != nil {
68
104
klog .ErrorS (err , "Fail to create udp connection" , constants .LogFieldRequestID , hdr .RequestID , constants .LogFieldDestAddr , dstAddr )
105
+ _ = writeACK (c , xnet.Acknowledgement {
106
+ Code : ackCodeFromErr (err ),
107
+ })
108
+ return
109
+ }
110
+ err = writeACK (c , xnet.Acknowledgement {
111
+ Code : xnet .AckCodeOK ,
112
+ })
113
+ if err != nil {
114
+ klog .ErrorS (err , "Fail to write ack" , constants .LogFieldRequestID , hdr .RequestID )
69
115
return
70
116
}
71
117
klog .InfoS ("Start proxy udp request" , constants .LogFieldRequestID , hdr .RequestID , constants .LogFieldDestAddr , dstAddr )
0 commit comments