| 
									
										
										
										
											2015-09-19 23:54:36 +02:00
										 |  |  | package protocol | 
					
						
							| 
									
										
										
										
											2015-09-16 21:13:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-09-21 20:56:07 +02:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2015-09-16 21:13:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 14:46:18 +02:00
										 |  |  | 	"github.com/v2ray/v2ray-core/common/alloc" | 
					
						
							| 
									
										
										
										
											2015-09-21 20:56:07 +02:00
										 |  |  | 	"github.com/v2ray/v2ray-core/common/log" | 
					
						
							| 
									
										
										
										
											2015-09-19 23:54:36 +02:00
										 |  |  | 	v2net "github.com/v2ray/v2ray-core/common/net" | 
					
						
							| 
									
										
										
										
											2015-11-03 18:20:28 +01:00
										 |  |  | 	"github.com/v2ray/v2ray-core/transport" | 
					
						
							| 
									
										
										
										
											2015-09-16 21:13:13 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 20:56:07 +02:00
										 |  |  | var ( | 
					
						
							|  |  |  | 	ErrorUnknownAddressType = errors.New("Unknown Address Type.") | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-16 21:13:13 +02:00
										 |  |  | type Socks5UDPRequest struct { | 
					
						
							| 
									
										
										
										
											2015-09-22 23:50:05 +02:00
										 |  |  | 	Fragment byte | 
					
						
							|  |  |  | 	Address  v2net.Address | 
					
						
							| 
									
										
										
										
											2015-10-08 14:46:18 +02:00
										 |  |  | 	Data     *alloc.Buffer | 
					
						
							| 
									
										
										
										
											2015-09-16 21:13:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 20:56:07 +02:00
										 |  |  | func (request *Socks5UDPRequest) Destination() v2net.Destination { | 
					
						
							| 
									
										
										
										
											2015-09-22 23:50:05 +02:00
										 |  |  | 	return v2net.NewUDPDestination(request.Address) | 
					
						
							| 
									
										
										
										
											2015-09-21 20:56:07 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 23:28:51 +02:00
										 |  |  | func (request *Socks5UDPRequest) Write(buffer *alloc.Buffer) { | 
					
						
							|  |  |  | 	buffer.AppendBytes(0, 0, request.Fragment) | 
					
						
							| 
									
										
										
										
											2015-10-05 16:58:14 +02:00
										 |  |  | 	switch { | 
					
						
							|  |  |  | 	case request.Address.IsIPv4(): | 
					
						
							| 
									
										
										
										
											2015-10-08 23:29:06 +02:00
										 |  |  | 		buffer.AppendBytes(AddrTypeIPv4).Append(request.Address.IP()) | 
					
						
							| 
									
										
										
										
											2015-10-05 16:58:14 +02:00
										 |  |  | 	case request.Address.IsIPv6(): | 
					
						
							| 
									
										
										
										
											2015-10-08 23:29:06 +02:00
										 |  |  | 		buffer.AppendBytes(AddrTypeIPv6).Append(request.Address.IP()) | 
					
						
							| 
									
										
										
										
											2015-10-05 16:58:14 +02:00
										 |  |  | 	case request.Address.IsDomain(): | 
					
						
							| 
									
										
										
										
											2015-10-08 23:29:06 +02:00
										 |  |  | 		buffer.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain()))).Append([]byte(request.Address.Domain())) | 
					
						
							| 
									
										
										
										
											2015-10-05 16:58:14 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-12-02 12:47:54 +01:00
										 |  |  | 	buffer.Append(request.Address.Port().Bytes()) | 
					
						
							| 
									
										
										
										
											2015-10-08 23:29:06 +02:00
										 |  |  | 	buffer.Append(request.Data.Value) | 
					
						
							| 
									
										
										
										
											2015-10-05 16:57:50 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-03 18:20:28 +01:00
										 |  |  | func ReadUDPRequest(packet []byte) (*Socks5UDPRequest, error) { | 
					
						
							|  |  |  | 	if len(packet) < 5 { | 
					
						
							|  |  |  | 		return nil, transport.CorruptedPacket | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	request := new(Socks5UDPRequest) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 20:56:07 +02:00
										 |  |  | 	// packet[0] and packet[1] are reserved | 
					
						
							| 
									
										
										
										
											2015-09-22 23:50:05 +02:00
										 |  |  | 	request.Fragment = packet[2] | 
					
						
							| 
									
										
										
										
											2015-09-21 20:56:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	addrType := packet[3] | 
					
						
							|  |  |  | 	var dataBegin int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch addrType { | 
					
						
							|  |  |  | 	case AddrTypeIPv4: | 
					
						
							| 
									
										
										
										
											2015-11-03 18:20:28 +01:00
										 |  |  | 		if len(packet) < 10 { | 
					
						
							|  |  |  | 			return nil, transport.CorruptedPacket | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-09-21 20:56:07 +02:00
										 |  |  | 		ip := packet[4:8] | 
					
						
							| 
									
										
										
										
											2015-12-02 20:44:01 +00:00
										 |  |  | 		port := v2net.PortFromBytes(packet[8:10]) | 
					
						
							| 
									
										
										
										
											2015-09-22 23:50:05 +02:00
										 |  |  | 		request.Address = v2net.IPAddress(ip, port) | 
					
						
							| 
									
										
										
										
											2015-09-21 20:56:07 +02:00
										 |  |  | 		dataBegin = 10 | 
					
						
							|  |  |  | 	case AddrTypeIPv6: | 
					
						
							| 
									
										
										
										
											2015-11-03 18:20:28 +01:00
										 |  |  | 		if len(packet) < 22 { | 
					
						
							|  |  |  | 			return nil, transport.CorruptedPacket | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-09-21 20:56:07 +02:00
										 |  |  | 		ip := packet[4:20] | 
					
						
							| 
									
										
										
										
											2015-12-02 20:44:01 +00:00
										 |  |  | 		port := v2net.PortFromBytes(packet[20:22]) | 
					
						
							| 
									
										
										
										
											2015-09-22 23:50:05 +02:00
										 |  |  | 		request.Address = v2net.IPAddress(ip, port) | 
					
						
							| 
									
										
										
										
											2015-09-21 20:56:07 +02:00
										 |  |  | 		dataBegin = 22 | 
					
						
							|  |  |  | 	case AddrTypeDomain: | 
					
						
							|  |  |  | 		domainLength := int(packet[4]) | 
					
						
							| 
									
										
										
										
											2015-11-03 18:20:28 +01:00
										 |  |  | 		if len(packet) < 5+domainLength+2 { | 
					
						
							|  |  |  | 			return nil, transport.CorruptedPacket | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-09-21 20:56:07 +02:00
										 |  |  | 		domain := string(packet[5 : 5+domainLength]) | 
					
						
							| 
									
										
										
										
											2015-12-02 20:44:01 +00:00
										 |  |  | 		port := v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2]) | 
					
						
							| 
									
										
										
										
											2015-09-22 23:50:05 +02:00
										 |  |  | 		request.Address = v2net.DomainAddress(domain, port) | 
					
						
							| 
									
										
										
										
											2015-09-21 20:56:07 +02:00
										 |  |  | 		dataBegin = 5 + domainLength + 2 | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		log.Warning("Unknown address type %d", addrType) | 
					
						
							| 
									
										
										
										
											2015-11-03 18:20:28 +01:00
										 |  |  | 		return nil, ErrorUnknownAddressType | 
					
						
							| 
									
										
										
										
											2015-09-21 20:56:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-03 18:20:28 +01:00
										 |  |  | 	if len(packet) > dataBegin { | 
					
						
							|  |  |  | 		request.Data = alloc.NewBuffer().Clear().Append(packet[dataBegin:]) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-09-16 21:13:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-03 18:20:28 +01:00
										 |  |  | 	return request, nil | 
					
						
							| 
									
										
										
										
											2015-09-16 21:13:13 +02:00
										 |  |  | } |