1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-06-26 09:25:23 +00:00
v2fly/transport/internet/domainsocket/listener.go

130 lines
2.7 KiB
Go
Raw Normal View History

2018-04-12 15:44:23 +00:00
// +build !windows
2018-08-27 18:56:49 +00:00
// +build !wasm
2019-02-01 19:08:21 +00:00
// +build !confonly
2018-04-12 15:44:23 +00:00
2017-10-31 05:51:31 +00:00
package domainsocket
2017-11-03 12:02:05 +00:00
import (
"context"
2018-04-09 15:09:24 +00:00
gotls "crypto/tls"
2018-03-16 04:35:12 +00:00
"os"
2018-04-09 15:09:24 +00:00
"strings"
2018-03-16 04:35:12 +00:00
"syscall"
2018-03-18 13:46:50 +00:00
2018-04-09 18:45:23 +00:00
"v2ray.com/core/common"
2018-04-09 15:09:24 +00:00
"v2ray.com/core/common/net"
"v2ray.com/core/transport/internet"
"v2ray.com/core/transport/internet/tls"
2017-11-03 12:02:05 +00:00
)
type Listener struct {
2018-04-09 15:09:24 +00:00
addr *net.UnixAddr
ln net.Listener
tlsConfig *gotls.Config
config *Config
addConn internet.ConnHandler
locker *fileLocker
2017-11-03 12:02:05 +00:00
}
func Listen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) {
settings := streamSettings.ProtocolSettings.(*Config)
2018-04-09 15:09:24 +00:00
addr, err := settings.GetUnixAddr()
if err != nil {
return nil, err
2018-03-18 13:46:50 +00:00
}
2018-04-09 15:09:24 +00:00
unixListener, err := net.ListenUnix("unix", addr)
if err != nil {
return nil, newError("failed to listen domain socket").Base(err).AtWarning()
2018-03-18 13:46:50 +00:00
}
2018-03-16 04:35:12 +00:00
2018-04-09 15:09:24 +00:00
ln := &Listener{
addr: addr,
ln: unixListener,
config: settings,
addConn: handler,
2018-03-18 13:46:50 +00:00
}
2018-03-16 04:35:12 +00:00
2018-04-09 15:09:24 +00:00
if !settings.Abstract {
ln.locker = &fileLocker{
path: settings.Path + ".lock",
}
if err := ln.locker.Acquire(); err != nil {
unixListener.Close()
return nil, err
2018-03-29 04:35:02 +00:00
}
2018-03-16 04:35:12 +00:00
}
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
2018-04-09 15:09:24 +00:00
ln.tlsConfig = config.GetTLSConfig()
2018-03-18 13:46:50 +00:00
}
2018-04-09 15:09:24 +00:00
go ln.run()
2018-03-18 13:46:50 +00:00
2018-04-09 15:09:24 +00:00
return ln, nil
2018-03-18 13:46:50 +00:00
}
2018-04-09 15:09:24 +00:00
func (ln *Listener) Addr() net.Addr {
return ln.addr
2018-03-18 13:46:50 +00:00
}
2018-04-09 15:09:24 +00:00
func (ln *Listener) Close() error {
2018-04-09 15:18:48 +00:00
if ln.locker != nil {
ln.locker.Release()
}
2018-04-09 15:09:24 +00:00
return ln.ln.Close()
}
2018-03-16 04:35:12 +00:00
2018-04-09 15:09:24 +00:00
func (ln *Listener) run() {
for {
conn, err := ln.ln.Accept()
2018-03-18 13:46:50 +00:00
if err != nil {
2018-04-09 15:09:24 +00:00
if strings.Contains(err.Error(), "closed") {
break
2018-03-18 13:46:50 +00:00
}
2018-04-09 15:09:24 +00:00
newError("failed to accepted raw connections").Base(err).AtWarning().WriteToLog()
continue
2018-03-18 13:46:50 +00:00
}
2018-04-09 15:09:24 +00:00
if ln.tlsConfig != nil {
conn = tls.Server(conn, ln.tlsConfig)
}
ln.addConn(internet.Connection(conn))
2018-03-18 13:46:50 +00:00
}
2017-11-03 12:02:05 +00:00
}
2018-03-11 05:44:21 +00:00
2018-04-09 15:09:24 +00:00
type fileLocker struct {
path string
file *os.File
2018-03-11 05:44:21 +00:00
}
2018-03-16 04:35:12 +00:00
2018-04-09 15:09:24 +00:00
func (fl *fileLocker) Acquire() error {
f, err := os.Create(fl.path)
2018-03-16 04:35:12 +00:00
if err != nil {
2018-04-09 15:09:24 +00:00
return err
2018-03-16 04:35:12 +00:00
}
2018-04-09 15:09:24 +00:00
if err := syscall.Flock(int(f.Fd()), syscall.LOCK_EX); err != nil {
f.Close()
return newError("failed to lock file: ", fl.path).Base(err)
2018-03-16 04:35:12 +00:00
}
2018-04-09 15:09:24 +00:00
fl.file = f
return nil
2018-03-18 13:46:50 +00:00
}
2018-04-09 15:09:24 +00:00
func (fl *fileLocker) Release() {
if err := syscall.Flock(int(fl.file.Fd()), syscall.LOCK_UN); err != nil {
newError("failed to unlock file: ", fl.path).Base(err).WriteToLog()
2018-03-18 13:46:50 +00:00
}
2018-04-09 15:09:24 +00:00
if err := fl.file.Close(); err != nil {
newError("failed to close file: ", fl.path).Base(err).WriteToLog()
2018-03-18 13:46:50 +00:00
}
2018-04-09 15:09:24 +00:00
if err := os.Remove(fl.path); err != nil {
newError("failed to remove file: ", fl.path).Base(err).WriteToLog()
2018-03-18 13:46:50 +00:00
}
2018-03-16 04:35:12 +00:00
}
2018-04-09 18:45:23 +00:00
func init() {
2018-08-06 11:48:35 +00:00
common.Must(internet.RegisterTransportListener(protocolName, Listen))
2018-04-09 18:45:23 +00:00
}