mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 15:44:01 +03:00
FILE / ScuroNeko/mtg
config/config.go
Исходный файл и его история в репозитории.
175 lines
4.3 KiB
Go
175 lines
4.3 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"fmt"
|
|
"net"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/juju/errors"
|
|
)
|
|
|
|
// Buffer sizes define internal socket buffer sizes.
|
|
const (
|
|
BufferWriteSize = 32 * 1024
|
|
BufferReadSize = 32 * 1024
|
|
BufferSizeCopy = 32 * 1024
|
|
|
|
TimeoutRead = time.Minute
|
|
TimeoutWrite = time.Minute
|
|
|
|
keepAlivePeriod = 20 * time.Second
|
|
)
|
|
|
|
// Config represents common configuration of mtg.
|
|
type Config struct {
|
|
Debug bool
|
|
Verbose bool
|
|
|
|
BindPort uint16
|
|
PublicIPv4Port uint16
|
|
PublicIPv6Port uint16
|
|
StatsPort uint16
|
|
|
|
BindIP net.IP
|
|
PublicIPv4 net.IP
|
|
PublicIPv6 net.IP
|
|
StatsIP net.IP
|
|
|
|
Secret []byte
|
|
}
|
|
|
|
// URLs contains links to the proxy (tg://, t.me) and their QR codes.
|
|
type URLs struct {
|
|
TG string `json:"tg_url"`
|
|
TMe string `json:"tme_url"`
|
|
TGQRCode string `json:"tg_qrcode"`
|
|
TMeQRCode string `json:"tme_qrcode"`
|
|
}
|
|
|
|
// IPURLs contains links to both ipv4 and ipv6 of the proxy.
|
|
type IPURLs struct {
|
|
IPv4 URLs `json:"ipv4"`
|
|
IPv6 URLs `json:"ipv6"`
|
|
}
|
|
|
|
// BindAddr returns connection for this server to bind to.
|
|
func (c *Config) BindAddr() string {
|
|
return getAddr(c.BindIP, c.BindPort)
|
|
}
|
|
|
|
// IPv4Addr returns connection string to ipv6 for mtproto proxy.
|
|
func (c *Config) IPv4Addr() string {
|
|
return getAddr(c.PublicIPv4, c.PublicIPv4Port)
|
|
}
|
|
|
|
// IPv6Addr returns connection string to ipv6 for mtproto proxy.
|
|
func (c *Config) IPv6Addr() string {
|
|
return getAddr(c.PublicIPv6, c.PublicIPv6Port)
|
|
}
|
|
|
|
// StatAddr returns connection string to the stats API.
|
|
func (c *Config) StatAddr() string {
|
|
return getAddr(c.StatsIP, c.StatsPort)
|
|
}
|
|
|
|
// GetURLs returns configured IPURLs instance with links to this server.
|
|
func (c *Config) GetURLs() IPURLs {
|
|
return IPURLs{
|
|
IPv4: getURLs(c.PublicIPv4, c.PublicIPv4Port, c.Secret),
|
|
IPv6: getURLs(c.PublicIPv6, c.PublicIPv6Port, c.Secret),
|
|
}
|
|
}
|
|
|
|
func getAddr(host fmt.Stringer, port uint16) string {
|
|
return net.JoinHostPort(host.String(), strconv.Itoa(int(port)))
|
|
}
|
|
|
|
// NewConfig returns new configuration. If required, it manages and
|
|
// fetches data from external sources. Parameters passed to this
|
|
// function, should come from command line arguments.
|
|
func NewConfig(debug, verbose bool, // nolint: gocyclo
|
|
bindIP net.IP, bindPort uint16,
|
|
publicIPv4 net.IP, PublicIPv4Port uint16,
|
|
publicIPv6 net.IP, publicIPv6Port uint16,
|
|
statsIP net.IP, statsPort uint16,
|
|
secret string) (*Config, error) {
|
|
if len(secret) != 32 {
|
|
return nil, errors.New("Telegram demands secret of length 32")
|
|
}
|
|
secretBytes, err := hex.DecodeString(secret)
|
|
if err != nil {
|
|
return nil, errors.Annotate(err, "Cannot create config")
|
|
}
|
|
|
|
if publicIPv4 == nil {
|
|
publicIPv4, err = getGlobalIPv4()
|
|
if err != nil {
|
|
return nil, errors.Errorf("Cannot get public IP")
|
|
}
|
|
}
|
|
if publicIPv4.To4() == nil {
|
|
return nil, errors.Errorf("IP %s is not IPv4", publicIPv4.String())
|
|
}
|
|
if PublicIPv4Port == 0 {
|
|
PublicIPv4Port = bindPort
|
|
}
|
|
|
|
if publicIPv6 == nil {
|
|
publicIPv6, err = getGlobalIPv6()
|
|
if err != nil {
|
|
publicIPv6 = publicIPv4
|
|
}
|
|
}
|
|
if publicIPv6.To16() == nil {
|
|
return nil, errors.Errorf("IP %s is not IPv6", publicIPv6.String())
|
|
}
|
|
if publicIPv6Port == 0 {
|
|
publicIPv6Port = bindPort
|
|
}
|
|
|
|
if statsIP == nil {
|
|
statsIP = publicIPv4
|
|
}
|
|
|
|
conf := &Config{
|
|
Debug: debug,
|
|
Verbose: verbose,
|
|
BindIP: bindIP,
|
|
BindPort: bindPort,
|
|
PublicIPv4: publicIPv4,
|
|
PublicIPv4Port: PublicIPv4Port,
|
|
PublicIPv6: publicIPv6,
|
|
PublicIPv6Port: publicIPv6Port,
|
|
StatsIP: statsIP,
|
|
StatsPort: statsPort,
|
|
Secret: secretBytes,
|
|
}
|
|
|
|
return conf, nil
|
|
}
|
|
|
|
// SetSocketOptions makes socket keepalive, sets buffer sizes
|
|
func SetSocketOptions(conn net.Conn) error {
|
|
socket := conn.(*net.TCPConn)
|
|
|
|
if err := socket.SetReadBuffer(BufferReadSize); err != nil {
|
|
return errors.Annotate(err, "Cannot set read buffer size")
|
|
}
|
|
if err := socket.SetWriteBuffer(BufferWriteSize); err != nil {
|
|
return errors.Annotate(err, "Cannot set write buffer size")
|
|
}
|
|
if err := socket.SetKeepAlive(true); err != nil {
|
|
return errors.Annotate(err, "Cannot make socket keepalive")
|
|
}
|
|
if err := socket.SetKeepAlivePeriod(keepAlivePeriod); err != nil {
|
|
return errors.Annotate(err, "Cannot set keepalive period")
|
|
}
|
|
if err := socket.SetNoDelay(true); err != nil {
|
|
return errors.Annotate(err, "Cannot activate nodelay for the socket")
|
|
}
|
|
|
|
return nil
|
|
}
|