diff --git a/transport/internet/domainsocket/listener.go b/transport/internet/domainsocket/listener.go index 2f56dd910..2c7b48a22 100644 --- a/transport/internet/domainsocket/listener.go +++ b/transport/internet/domainsocket/listener.go @@ -84,11 +84,11 @@ func (ls *Listener) LowerUP() error { newError(err).AtDebug().WriteToLog() return newError("Unable to acquire lock for filesystem based unix domain socket").Base(err) } - } - err = cleansePath(ls.path) - if err != nil { - return newError("Unable to cleanse path for the creation of unix domain socket").Base(err) + err = cleansePath(ls.path) + if err != nil { + return newError("Unable to cleanse path for the creation of unix domain socket").Base(err) + } } addr := new(net.UnixAddr) @@ -115,11 +115,12 @@ func (ls *Listener) UP(listener chan<- net.Conn, allowkick bool) error { return err } ls.listenerChan = listener - if ls.state.Has(STATE_UP) { + if !ls.state.Has(STATE_UP) { cctx, cancel := context.WithCancel(ls.ctx) ls.cancal = cancel go ls.uploop(cctx) } + ls.state.Set(STATE_UP) return nil } @@ -200,7 +201,7 @@ func giveupLock(locker *os.File) error { func cleansePath(path string) error { _, err := os.Stat(path) - if err == os.ErrNotExist { + if err != nil { return nil } err = os.Remove(path) diff --git a/transport/internet/domainsocket/listener_test.go b/transport/internet/domainsocket/listener_test.go new file mode 100644 index 000000000..f8c193e0b --- /dev/null +++ b/transport/internet/domainsocket/listener_test.go @@ -0,0 +1,94 @@ +package domainsocket_test + +import ( + "context" + "net" + "testing" + "time" + + "v2ray.com/core/transport/internet/domainsocket" + "v2ray.com/ext/assert" +) + +func TestListenAbstract(t *testing.T) { + listener, err := domainsocket.ListenDS(context.Background(), "\x00V2RayDimension/TestListenAbstract") + asrt := assert.With(t) + asrt(err, assert.IsNil) + asrt(listener, assert.IsNotNil) +} + +func TestListen(t *testing.T) { + listener, err := domainsocket.ListenDS(context.Background(), "/tmp/ts") + asrt := assert.With(t) + asrt(err, assert.IsNil) + asrt(listener, assert.IsNotNil) + errolu := listener.LowerUP() + asrt(errolu, assert.IsNil) + ctx, fin := context.WithCancel(context.Background()) + chi := make(chan net.Conn, 2) + go func() { + for { + select { + case conn := <-chi: + test := make([]byte, 256) + nc, errc := conn.Read(test) + asrt(errc, assert.IsNil) + conn.Write(test[:nc]) + time.Sleep(time.Second) + conn.Close() + case <-ctx.Done(): + return + } + } + }() + listener.UP(chi, false) + con, erro := net.Dial("unix", "/tmp/ts") + asrt(erro, assert.IsNil) + b := []byte("ABC") + c := []byte("XXX") + _, erron := con.Write(b) + asrt(erron, assert.IsNil) + con.Read(c) + con.Close() + asrt(b[0]-c[0] == 0, assert.IsTrue) + fin() + listener.Down() +} + +func TestListenA(t *testing.T) { + listener, err := domainsocket.ListenDS(context.Background(), "\x00/tmp/ts") + asrt := assert.With(t) + asrt(err, assert.IsNil) + asrt(listener, assert.IsNotNil) + errolu := listener.LowerUP() + asrt(errolu, assert.IsNil) + ctx, fin := context.WithCancel(context.Background()) + chi := make(chan net.Conn, 2) + go func() { + for { + select { + case conn := <-chi: + test := make([]byte, 256) + nc, errc := conn.Read(test) + asrt(errc, assert.IsNil) + conn.Write(test[:nc]) + time.Sleep(time.Second) + conn.Close() + case <-ctx.Done(): + return + } + } + }() + listener.UP(chi, false) + con, erro := net.Dial("unix", "\x00/tmp/ts") + asrt(erro, assert.IsNil) + b := []byte("ABC") + c := []byte("XXX") + _, erron := con.Write(b) + asrt(erron, assert.IsNil) + con.Read(c) + con.Close() + asrt(b[0]-c[0] == 0, assert.IsTrue) + fin() + listener.Down() +}