github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/functions_test.go (about) 1 package core_test 2 3 import ( 4 "context" 5 "crypto/rand" 6 "io" 7 "testing" 8 "time" 9 10 "github.com/google/go-cmp/cmp" 11 "google.golang.org/protobuf/proto" 12 "google.golang.org/protobuf/types/known/anypb" 13 14 core "github.com/v2fly/v2ray-core/v5" 15 "github.com/v2fly/v2ray-core/v5/app/dispatcher" 16 "github.com/v2fly/v2ray-core/v5/app/proxyman" 17 "github.com/v2fly/v2ray-core/v5/common" 18 "github.com/v2fly/v2ray-core/v5/common/net" 19 "github.com/v2fly/v2ray-core/v5/common/serial" 20 "github.com/v2fly/v2ray-core/v5/proxy/freedom" 21 "github.com/v2fly/v2ray-core/v5/testing/servers/tcp" 22 "github.com/v2fly/v2ray-core/v5/testing/servers/udp" 23 ) 24 25 func xor(b []byte) []byte { 26 r := make([]byte, len(b)) 27 for i, v := range b { 28 r[i] = v ^ 'c' 29 } 30 return r 31 } 32 33 func xor2(b []byte) []byte { 34 r := make([]byte, len(b)) 35 for i, v := range b { 36 r[i] = v ^ 'd' 37 } 38 return r 39 } 40 41 func TestV2RayDial(t *testing.T) { 42 tcpServer := tcp.Server{ 43 MsgProcessor: xor, 44 } 45 dest, err := tcpServer.Start() 46 common.Must(err) 47 defer tcpServer.Close() 48 49 config := &core.Config{ 50 App: []*anypb.Any{ 51 serial.ToTypedMessage(&dispatcher.Config{}), 52 serial.ToTypedMessage(&proxyman.InboundConfig{}), 53 serial.ToTypedMessage(&proxyman.OutboundConfig{}), 54 }, 55 Outbound: []*core.OutboundHandlerConfig{ 56 { 57 ProxySettings: serial.ToTypedMessage(&freedom.Config{}), 58 }, 59 }, 60 } 61 62 cfgBytes, err := proto.Marshal(config) 63 common.Must(err) 64 65 server, err := core.StartInstance(core.FormatProtobuf, cfgBytes) 66 common.Must(err) 67 defer server.Close() 68 69 conn, err := core.Dial(context.Background(), server, dest) 70 common.Must(err) 71 defer conn.Close() 72 73 const size = 10240 * 1024 74 payload := make([]byte, size) 75 common.Must2(rand.Read(payload)) 76 77 if _, err := conn.Write(payload); err != nil { 78 t.Fatal(err) 79 } 80 81 receive := make([]byte, size) 82 if _, err := io.ReadFull(conn, receive); err != nil { 83 t.Fatal("failed to read all response: ", err) 84 } 85 86 if r := cmp.Diff(xor(receive), payload); r != "" { 87 t.Error(r) 88 } 89 } 90 91 func TestV2RayDialUDPConn(t *testing.T) { 92 udpServer := udp.Server{ 93 MsgProcessor: xor, 94 } 95 dest, err := udpServer.Start() 96 common.Must(err) 97 defer udpServer.Close() 98 99 config := &core.Config{ 100 App: []*anypb.Any{ 101 serial.ToTypedMessage(&dispatcher.Config{}), 102 serial.ToTypedMessage(&proxyman.InboundConfig{}), 103 serial.ToTypedMessage(&proxyman.OutboundConfig{}), 104 }, 105 Outbound: []*core.OutboundHandlerConfig{ 106 { 107 ProxySettings: serial.ToTypedMessage(&freedom.Config{}), 108 }, 109 }, 110 } 111 112 cfgBytes, err := proto.Marshal(config) 113 common.Must(err) 114 115 server, err := core.StartInstance(core.FormatProtobuf, cfgBytes) 116 common.Must(err) 117 defer server.Close() 118 119 conn, err := core.Dial(context.Background(), server, dest) 120 common.Must(err) 121 defer conn.Close() 122 123 const size = 1024 124 payload := make([]byte, size) 125 common.Must2(rand.Read(payload)) 126 127 for i := 0; i < 2; i++ { 128 if _, err := conn.Write(payload); err != nil { 129 t.Fatal(err) 130 } 131 } 132 133 time.Sleep(time.Millisecond * 500) 134 135 receive := make([]byte, size*2) 136 for i := 0; i < 2; i++ { 137 n, err := conn.Read(receive) 138 if err != nil { 139 t.Fatal("expect no error, but got ", err) 140 } 141 if n != size { 142 t.Fatal("expect read size ", size, " but got ", n) 143 } 144 145 if r := cmp.Diff(xor(receive[:n]), payload); r != "" { 146 t.Fatal(r) 147 } 148 } 149 } 150 151 func TestV2RayDialUDP(t *testing.T) { 152 udpServer1 := udp.Server{ 153 MsgProcessor: xor, 154 } 155 dest1, err := udpServer1.Start() 156 common.Must(err) 157 defer udpServer1.Close() 158 159 udpServer2 := udp.Server{ 160 MsgProcessor: xor2, 161 } 162 dest2, err := udpServer2.Start() 163 common.Must(err) 164 defer udpServer2.Close() 165 166 config := &core.Config{ 167 App: []*anypb.Any{ 168 serial.ToTypedMessage(&dispatcher.Config{}), 169 serial.ToTypedMessage(&proxyman.InboundConfig{}), 170 serial.ToTypedMessage(&proxyman.OutboundConfig{}), 171 }, 172 Outbound: []*core.OutboundHandlerConfig{ 173 { 174 ProxySettings: serial.ToTypedMessage(&freedom.Config{}), 175 }, 176 }, 177 } 178 179 cfgBytes, err := proto.Marshal(config) 180 common.Must(err) 181 182 server, err := core.StartInstance(core.FormatProtobuf, cfgBytes) 183 common.Must(err) 184 defer server.Close() 185 186 conn, err := core.DialUDP(context.Background(), server) 187 common.Must(err) 188 defer conn.Close() 189 190 const size = 1024 191 { 192 payload := make([]byte, size) 193 common.Must2(rand.Read(payload)) 194 195 if _, err := conn.WriteTo(payload, &net.UDPAddr{ 196 IP: dest1.Address.IP(), 197 Port: int(dest1.Port), 198 }); err != nil { 199 t.Fatal(err) 200 } 201 202 receive := make([]byte, size) 203 if _, _, err := conn.ReadFrom(receive); err != nil { 204 t.Fatal(err) 205 } 206 207 if r := cmp.Diff(xor(receive), payload); r != "" { 208 t.Error(r) 209 } 210 } 211 212 { 213 payload := make([]byte, size) 214 common.Must2(rand.Read(payload)) 215 216 if _, err := conn.WriteTo(payload, &net.UDPAddr{ 217 IP: dest2.Address.IP(), 218 Port: int(dest2.Port), 219 }); err != nil { 220 t.Fatal(err) 221 } 222 223 receive := make([]byte, size) 224 if _, _, err := conn.ReadFrom(receive); err != nil { 225 t.Fatal(err) 226 } 227 228 if r := cmp.Diff(xor2(receive), payload); r != "" { 229 t.Error(r) 230 } 231 } 232 }