github.com/TeaOSLab/EdgeNode@v1.3.8/internal/nodes/listener.go (about)

     1  package nodes
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
     7  	"github.com/TeaOSLab/EdgeNode/internal/events"
     8  	"github.com/TeaOSLab/EdgeNode/internal/goman"
     9  	"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
    10  	"golang.org/x/net/ipv4"
    11  	"golang.org/x/net/ipv6"
    12  	"net"
    13  	"strings"
    14  	"sync"
    15  )
    16  
    17  type Listener struct {
    18  	group    *serverconfigs.ServerAddressGroup
    19  	listener ListenerInterface // 监听器
    20  
    21  	locker sync.RWMutex
    22  }
    23  
    24  func NewListener() *Listener {
    25  	return &Listener{}
    26  }
    27  
    28  func (this *Listener) Reload(group *serverconfigs.ServerAddressGroup) {
    29  	this.locker.Lock()
    30  	this.group = group
    31  	if this.listener != nil {
    32  		this.listener.Reload(group)
    33  	}
    34  	this.locker.Unlock()
    35  }
    36  
    37  func (this *Listener) FullAddr() string {
    38  	if this.group != nil {
    39  		return this.group.FullAddr()
    40  	}
    41  	return ""
    42  }
    43  
    44  func (this *Listener) Listen() error {
    45  	if this.group == nil {
    46  		return nil
    47  	}
    48  	var protocol = this.group.Protocol()
    49  	if protocol.IsUDPFamily() {
    50  		return this.listenUDP()
    51  	}
    52  	return this.listenTCP()
    53  }
    54  
    55  func (this *Listener) listenTCP() error {
    56  	if this.group == nil {
    57  		return nil
    58  	}
    59  	var protocol = this.group.Protocol()
    60  
    61  	tcpListener, err := this.createTCPListener()
    62  	if err != nil {
    63  		return err
    64  	}
    65  	var netListener = NewClientListener(tcpListener, protocol.IsHTTPFamily() || protocol.IsHTTPSFamily())
    66  	events.OnKey(events.EventQuit, this, func() {
    67  		remotelogs.Println("LISTENER", "quit "+this.group.FullAddr())
    68  		_ = netListener.Close()
    69  	})
    70  
    71  	switch protocol {
    72  	case serverconfigs.ProtocolHTTP, serverconfigs.ProtocolHTTP4, serverconfigs.ProtocolHTTP6:
    73  		this.listener = &HTTPListener{
    74  			BaseListener: BaseListener{Group: this.group},
    75  			Listener:     netListener,
    76  		}
    77  	case serverconfigs.ProtocolHTTPS, serverconfigs.ProtocolHTTPS4, serverconfigs.ProtocolHTTPS6:
    78  		netListener.SetIsTLS(true)
    79  		this.listener = &HTTPListener{
    80  			BaseListener: BaseListener{Group: this.group},
    81  			Listener:     netListener,
    82  		}
    83  	case serverconfigs.ProtocolTCP, serverconfigs.ProtocolTCP4, serverconfigs.ProtocolTCP6:
    84  		this.listener = &TCPListener{
    85  			BaseListener: BaseListener{Group: this.group},
    86  			Listener:     netListener,
    87  		}
    88  	case serverconfigs.ProtocolTLS, serverconfigs.ProtocolTLS4, serverconfigs.ProtocolTLS6:
    89  		netListener.SetIsTLS(true)
    90  		this.listener = &TCPListener{
    91  			BaseListener: BaseListener{Group: this.group},
    92  			Listener:     netListener,
    93  		}
    94  	default:
    95  		return errors.New("unknown protocol '" + protocol.String() + "'")
    96  	}
    97  
    98  	this.listener.Init()
    99  
   100  	goman.New(func() {
   101  		err := this.listener.Serve()
   102  		if err != nil {
   103  			// 在这里屏蔽accept错误,防止在优雅关闭的时候有多余的提示
   104  			opErr, ok := err.(*net.OpError)
   105  			if ok && opErr.Op == "accept" {
   106  				return
   107  			}
   108  
   109  			// 打印其他错误
   110  			remotelogs.Error("LISTENER", err.Error())
   111  		}
   112  	})
   113  
   114  	return nil
   115  }
   116  
   117  func (this *Listener) listenUDP() error {
   118  	var addr = this.group.Addr()
   119  
   120  	var ipv4PacketListener *ipv4.PacketConn
   121  	var ipv6PacketListener *ipv6.PacketConn
   122  
   123  	host, _, err := net.SplitHostPort(addr)
   124  	if err != nil {
   125  		return err
   126  	}
   127  
   128  	if len(host) == 0 {
   129  		// ipv4
   130  		ipv4Listener, err := this.createUDPIPv4Listener()
   131  		if err == nil {
   132  			ipv4PacketListener = ipv4.NewPacketConn(ipv4Listener)
   133  		} else {
   134  			remotelogs.Error("LISTENER", "create udp ipv4 listener '"+addr+"': "+err.Error())
   135  		}
   136  
   137  		// ipv6
   138  		ipv6Listener, err := this.createUDPIPv6Listener()
   139  		if err == nil {
   140  			ipv6PacketListener = ipv6.NewPacketConn(ipv6Listener)
   141  		} else {
   142  			remotelogs.Error("LISTENER", "create udp ipv6 listener '"+addr+"': "+err.Error())
   143  		}
   144  	} else if strings.Contains(host, ":") { // ipv6
   145  		ipv6Listener, err := this.createUDPIPv6Listener()
   146  		if err == nil {
   147  			ipv6PacketListener = ipv6.NewPacketConn(ipv6Listener)
   148  		} else {
   149  			remotelogs.Error("LISTENER", "create udp ipv6 listener '"+addr+"': "+err.Error())
   150  		}
   151  	} else { // ipv4
   152  		ipv4Listener, err := this.createUDPIPv4Listener()
   153  		if err == nil {
   154  			ipv4PacketListener = ipv4.NewPacketConn(ipv4Listener)
   155  		} else {
   156  			remotelogs.Error("LISTENER", "create udp ipv4 listener '"+addr+"': "+err.Error())
   157  		}
   158  	}
   159  
   160  	events.OnKey(events.EventQuit, this, func() {
   161  		remotelogs.Println("LISTENER", "quit "+this.group.FullAddr())
   162  
   163  		if ipv4PacketListener != nil {
   164  			_ = ipv4PacketListener.Close()
   165  		}
   166  
   167  		if ipv6PacketListener != nil {
   168  			_ = ipv6PacketListener.Close()
   169  		}
   170  	})
   171  
   172  	this.listener = &UDPListener{
   173  		BaseListener: BaseListener{Group: this.group},
   174  		IPv4Listener: ipv4PacketListener,
   175  		IPv6Listener: ipv6PacketListener,
   176  	}
   177  
   178  	goman.New(func() {
   179  		err := this.listener.Serve()
   180  		if err != nil {
   181  			remotelogs.Error("LISTENER", err.Error())
   182  		}
   183  	})
   184  
   185  	return nil
   186  }
   187  
   188  func (this *Listener) Close() error {
   189  	events.Remove(this)
   190  
   191  	if this.listener == nil {
   192  		return nil
   193  	}
   194  	return this.listener.Close()
   195  }
   196  
   197  // 创建TCP监听器
   198  func (this *Listener) createTCPListener() (net.Listener, error) {
   199  	var listenConfig = net.ListenConfig{
   200  		Control:   nil,
   201  		KeepAlive: 0,
   202  	}
   203  
   204  	switch this.group.Protocol() {
   205  	case serverconfigs.ProtocolHTTP4, serverconfigs.ProtocolHTTPS4, serverconfigs.ProtocolTLS4:
   206  		return listenConfig.Listen(context.Background(), "tcp4", this.group.Addr())
   207  	case serverconfigs.ProtocolHTTP6, serverconfigs.ProtocolHTTPS6, serverconfigs.ProtocolTLS6:
   208  		return listenConfig.Listen(context.Background(), "tcp6", this.group.Addr())
   209  	}
   210  
   211  	return listenConfig.Listen(context.Background(), "tcp", this.group.Addr())
   212  }
   213  
   214  // 创建UDP IPv4监听器
   215  func (this *Listener) createUDPIPv4Listener() (*net.UDPConn, error) {
   216  	addr, err := net.ResolveUDPAddr("udp", this.group.Addr())
   217  	if err != nil {
   218  		return nil, err
   219  	}
   220  	return net.ListenUDP("udp4", addr)
   221  }
   222  
   223  // 创建UDP监听器
   224  func (this *Listener) createUDPIPv6Listener() (*net.UDPConn, error) {
   225  	addr, err := net.ResolveUDPAddr("udp", this.group.Addr())
   226  	if err != nil {
   227  		return nil, err
   228  	}
   229  	return net.ListenUDP("udp6", addr)
   230  }