Fetch the repository succeeded.
/*
* Copyright (c) 2021. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package traffic
import (
"errors"
"net"
"net/url"
"strconv"
"strings"
"gitee.com/meng_mengs_boys/eosc/log"
"github.com/soheilhy/cmux"
)
var (
ErrorInvalidListener = errors.New("invalid port-reqiure")
)
type ITraffic interface {
Listen(addrs ...string) (tcp []net.Listener, ssl []net.Listener)
IsStop() bool
Close()
}
type Traffic struct {
*TrafficData
}
const (
bitTCP = 1 << iota
bitSSL
bitBoth = bitTCP | bitSSL
)
func (t *Traffic) Listen(addrs ...string) (tcp []net.Listener, ssl []net.Listener) {
schemes := make(map[string]int)
for _, addr := range addrs {
addrValue, isSSl := readAddr(addr)
if isSSl {
schemes[addrValue] = schemes[addrValue] | bitSSL
} else {
schemes[addrValue] = schemes[addrValue] | bitTCP
}
}
for addr, v := range schemes {
listener, has := t.data[addr]
if !has {
continue
}
switch v {
case bitBoth:
{
cMux := cmux.New(listener)
ssl = append(ssl, cMux.Match(cmux.TLS()))
tcp = append(tcp, cMux.Match(cmux.Any()))
go runMux(cMux)
}
case bitTCP:
tcp = append(tcp, listener)
case bitSSL:
ssl = append(ssl, listener)
}
}
return tcp, ssl
}
func runMux(c cmux.CMux) {
err := c.Serve()
if err != nil {
log.Info("close cmux:", err)
}
}
func readAddr(addr string) (string, bool) {
u, err := url.Parse(addr)
if err != nil {
u = &url.URL{Scheme: "tcp", Host: addr}
}
ssl := false
port, _ := strconv.Atoi(u.Port())
switch strings.ToLower(u.Scheme) {
case "https", "ssl", "tls":
ssl = true
if port == 0 {
port = 443
}
default:
ssl = false
if port == 0 {
port = 80
}
}
parseIP := net.ParseIP(u.Hostname())
tcpAddr := net.TCPAddr{IP: parseIP, Port: port}
return tcpAddr.String(), ssl
}
func NewTraffic(trafficData *TrafficData) ITraffic {
return &Traffic{TrafficData: trafficData}
}
func FromArg(traffics []*PbTraffic) ITraffic {
listeners := toListeners(traffics)
log.Debug("read listeners: ", len(listeners))
data := NewTrafficData(listeners)
return NewTraffic(data)
}
type EmptyTraffic struct {
}
func (e *EmptyTraffic) Listen(addrs ...string) (tcp []net.Listener, ssl []net.Listener) {
return nil, nil
}
func (e *EmptyTraffic) IsStop() bool {
return false
}
func (e *EmptyTraffic) Close() {
}
func NewEmptyTraffic() ITraffic {
return &EmptyTraffic{}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。