Feature: support vmess udp

This commit is contained in:
Dreamacro 2019-04-25 16:32:15 +08:00
parent 936ea3aa55
commit 762f227512
4 changed files with 20 additions and 2 deletions

View File

@ -230,5 +230,5 @@ https://clash.gitbook.io/
- [x] Complementing the necessary rule operators - [x] Complementing the necessary rule operators
- [x] Redir proxy - [x] Redir proxy
- [ ] UDP support (vmess) - [x] UDP support
- [ ] Connection manager - [ ] Connection manager

View File

@ -24,6 +24,7 @@ type VmessOption struct {
AlterID int `proxy:"alterId"` AlterID int `proxy:"alterId"`
Cipher string `proxy:"cipher"` Cipher string `proxy:"cipher"`
TLS bool `proxy:"tls,omitempty"` TLS bool `proxy:"tls,omitempty"`
UDP bool `proxy:"udp,omitempty"`
Network string `proxy:"network,omitempty"` Network string `proxy:"network,omitempty"`
WSPath string `proxy:"ws-path,omitempty"` WSPath string `proxy:"ws-path,omitempty"`
WSHeaders map[string]string `proxy:"ws-headers,omitempty"` WSHeaders map[string]string `proxy:"ws-headers,omitempty"`
@ -40,6 +41,16 @@ func (v *Vmess) Dial(metadata *C.Metadata) (net.Conn, error) {
return c, err return c, err
} }
func (v *Vmess) DialUDP(metadata *C.Metadata) (net.PacketConn, net.Addr, error) {
c, err := net.DialTimeout("tcp", v.server, tcpTimeout)
if err != nil {
return nil, nil, fmt.Errorf("%s connect error", v.server)
}
tcpKeepAlive(c)
c, err = v.client.New(c, parseVmessAddr(metadata))
return &fakeUDPConn{Conn: c}, c.LocalAddr(), err
}
func NewVmess(option VmessOption) (*Vmess, error) { func NewVmess(option VmessOption) (*Vmess, error) {
security := strings.ToLower(option.Cipher) security := strings.ToLower(option.Cipher)
client, err := vmess.NewClient(vmess.Config{ client, err := vmess.NewClient(vmess.Config{
@ -63,6 +74,7 @@ func NewVmess(option VmessOption) (*Vmess, error) {
Base: &Base{ Base: &Base{
name: option.Name, name: option.Name,
tp: C.Vmess, tp: C.Vmess,
udp: option.UDP,
}, },
server: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)), server: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)),
client: client, client: client,
@ -90,6 +102,7 @@ func parseVmessAddr(metadata *C.Metadata) *vmess.DstAddr {
port, _ := strconv.Atoi(metadata.Port) port, _ := strconv.Atoi(metadata.Port)
return &vmess.DstAddr{ return &vmess.DstAddr{
UDP: metadata.NetWork == C.UDP,
AddrType: addrType, AddrType: addrType,
Addr: addr, Addr: addr,
Port: uint(port), Port: uint(port),

View File

@ -77,7 +77,11 @@ func (vc *Conn) sendRequest() error {
// P Sec Reserve Cmd // P Sec Reserve Cmd
buf.WriteByte(byte(p<<4) | byte(vc.security)) buf.WriteByte(byte(p<<4) | byte(vc.security))
buf.WriteByte(0) buf.WriteByte(0)
if vc.dst.UDP {
buf.WriteByte(CommandUDP)
} else {
buf.WriteByte(CommandTCP) buf.WriteByte(CommandTCP)
}
// Port AddrType Addr // Port AddrType Addr
binary.Write(buf, binary.BigEndian, uint16(vc.dst.Port)) binary.Write(buf, binary.BigEndian, uint16(vc.dst.Port))

View File

@ -57,6 +57,7 @@ const (
// DstAddr store destination address // DstAddr store destination address
type DstAddr struct { type DstAddr struct {
UDP bool
AddrType byte AddrType byte
Addr []byte Addr []byte
Port uint Port uint