| 
					
				 | 
			
			
				@@ -615,6 +615,130 @@ func TestShadowsocksAES128GCMUDP(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	CloseAllServers(servers) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func TestShadowsocksAES128GCMUDPMux(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert := With(t) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	udpServer := udp.Server{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		MsgProcessor: xor, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dest, err := udpServer.Start() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert(err, IsNil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	defer udpServer.Close() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	account := serial.ToTypedMessage(&shadowsocks.Account{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Password:   "shadowsocks-password", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		CipherType: shadowsocks.CipherType_AES_128_GCM, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	serverPort := tcp.PickPort() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	serverConfig := &core.Config{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		App: []*serial.TypedMessage{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			serial.ToTypedMessage(&log.Config{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ErrorLogLevel: clog.Severity_Debug, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ErrorLogType:  log.LogType_Console, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Inbound: []*core.InboundHandlerConfig{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					PortRange: net.SinglePortRange(serverPort), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					Listen:    net.NewIPOrDomain(net.LocalHostIP), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ProxySettings: serial.ToTypedMessage(&shadowsocks.ServerConfig{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					UdpEnabled: false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					User: &protocol.User{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						Account: account, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						Level:   1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Outbound: []*core.OutboundHandlerConfig{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ProxySettings: serial.ToTypedMessage(&freedom.Config{}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	clientPort := tcp.PickPort() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	clientConfig := &core.Config{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		App: []*serial.TypedMessage{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			serial.ToTypedMessage(&log.Config{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ErrorLogLevel: clog.Severity_Debug, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ErrorLogType:  log.LogType_Console, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Inbound: []*core.InboundHandlerConfig{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					PortRange: net.SinglePortRange(clientPort), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					Listen:    net.NewIPOrDomain(net.LocalHostIP), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					Address: net.NewIPOrDomain(dest.Address), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					Port:    uint32(dest.Port), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					NetworkList: &net.NetworkList{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						Network: []net.Network{net.Network_UDP}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Outbound: []*core.OutboundHandlerConfig{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					MultiplexSettings: &proxyman.MultiplexingConfig{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						Enabled:     true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						Concurrency: 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					Server: []*protocol.ServerEndpoint{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							Address: net.NewIPOrDomain(net.LocalHostIP), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							Port:    uint32(serverPort), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							User: []*protocol.User{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									Account: account, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	servers, err := InitializeServerConfigs(serverConfig, clientConfig) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert(err, IsNil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	var wg sync.WaitGroup 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	wg.Add(10) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for i := 0; i < 10; i++ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		go func() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			conn, err := net.DialUDP("udp", nil, &net.UDPAddr{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				IP:   []byte{127, 0, 0, 1}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Port: int(clientPort), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			assert(err, IsNil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			payload := make([]byte, 1024) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			rand.Read(payload) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			nBytes, err := conn.Write([]byte(payload)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			assert(err, IsNil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			assert(nBytes, Equals, len(payload)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			response := readFrom(conn, time.Second*5, 1024) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			assert(response, Equals, xor([]byte(payload))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			assert(conn.Close(), IsNil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			wg.Done() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	wg.Wait() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	CloseAllServers(servers) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func TestShadowsocksAES256GCMConformance(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	assert := With(t) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |