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 }