|
|
@@ -2,7 +2,6 @@ package dokodemo
|
|
|
|
|
|
import (
|
|
|
"io"
|
|
|
- "net"
|
|
|
"sync"
|
|
|
|
|
|
"github.com/v2ray/v2ray-core/app"
|
|
|
@@ -22,7 +21,7 @@ type DokodemoDoor struct {
|
|
|
port v2net.Port
|
|
|
space app.Space
|
|
|
tcpListener *hub.TCPListener
|
|
|
- udpConn *net.UDPConn
|
|
|
+ udpHub *hub.UDPHub
|
|
|
listeningPort v2net.Port
|
|
|
}
|
|
|
|
|
|
@@ -47,10 +46,10 @@ func (this *DokodemoDoor) Close() {
|
|
|
this.tcpListener = nil
|
|
|
this.tcpMutex.Unlock()
|
|
|
}
|
|
|
- if this.udpConn != nil {
|
|
|
- this.udpConn.Close()
|
|
|
+ if this.udpHub != nil {
|
|
|
this.udpMutex.Lock()
|
|
|
- this.udpConn = nil
|
|
|
+ this.udpHub.Close()
|
|
|
+ this.udpHub = nil
|
|
|
this.udpMutex.Unlock()
|
|
|
}
|
|
|
}
|
|
|
@@ -82,52 +81,32 @@ func (this *DokodemoDoor) Listen(port v2net.Port) error {
|
|
|
}
|
|
|
|
|
|
func (this *DokodemoDoor) ListenUDP(port v2net.Port) error {
|
|
|
- udpConn, err := net.ListenUDP("udp", &net.UDPAddr{
|
|
|
- IP: []byte{0, 0, 0, 0},
|
|
|
- Port: int(port),
|
|
|
- Zone: "",
|
|
|
- })
|
|
|
+ udpHub, err := hub.ListenUDP(port, this.handleUDPPackets)
|
|
|
if err != nil {
|
|
|
log.Error("Dokodemo failed to listen on port ", port, ": ", err)
|
|
|
return err
|
|
|
}
|
|
|
this.udpMutex.Lock()
|
|
|
- this.udpConn = udpConn
|
|
|
+ this.udpHub = udpHub
|
|
|
this.udpMutex.Unlock()
|
|
|
- go this.handleUDPPackets()
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (this *DokodemoDoor) handleUDPPackets() {
|
|
|
- for this.accepting {
|
|
|
- buffer := alloc.NewBuffer()
|
|
|
+func (this *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, dest v2net.Destination) {
|
|
|
+ packet := v2net.NewPacket(v2net.UDPDestination(this.address, this.port), payload, false)
|
|
|
+ ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
|
|
|
+ close(ray.InboundInput())
|
|
|
+
|
|
|
+ for resp := range ray.InboundOutput() {
|
|
|
this.udpMutex.RLock()
|
|
|
if !this.accepting {
|
|
|
this.udpMutex.RUnlock()
|
|
|
+ resp.Release()
|
|
|
return
|
|
|
}
|
|
|
- nBytes, addr, err := this.udpConn.ReadFromUDP(buffer.Value)
|
|
|
+ this.udpHub.WriteTo(resp.Value, dest)
|
|
|
this.udpMutex.RUnlock()
|
|
|
- buffer.Slice(0, nBytes)
|
|
|
- if err != nil {
|
|
|
- buffer.Release()
|
|
|
- log.Error("Dokodemo failed to read from UDP: ", err)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- packet := v2net.NewPacket(v2net.UDPDestination(this.address, this.port), buffer, false)
|
|
|
- ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
|
|
|
- close(ray.InboundInput())
|
|
|
-
|
|
|
- for payload := range ray.InboundOutput() {
|
|
|
- this.udpMutex.RLock()
|
|
|
- if !this.accepting {
|
|
|
- this.udpMutex.RUnlock()
|
|
|
- return
|
|
|
- }
|
|
|
- this.udpConn.WriteToUDP(payload.Value, addr)
|
|
|
- this.udpMutex.RUnlock()
|
|
|
- }
|
|
|
+ resp.Release()
|
|
|
}
|
|
|
}
|
|
|
|