mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 22:24:02 +03:00
Bugfix rpc handshake
This commit is contained in:
+1
-2
@@ -32,9 +32,8 @@ func DirectInit(conn net.Conn, conf *config.Config) (*mtproto.ConnectionOpts, wr
|
|||||||
return nil, nil, errors.Annotate(err, "Cannot parse obfuscated frame")
|
return nil, nil, errors.Annotate(err, "Cannot parse obfuscated frame")
|
||||||
}
|
}
|
||||||
connOpts.ConnectionProto = mtproto.ConnectionProtocolAny
|
connOpts.ConnectionProto = mtproto.ConnectionProtocolAny
|
||||||
connOpts.ClientAddr = conn.RemoteAddr().(*net.TCPAddr)
|
|
||||||
|
|
||||||
socket := wrappers.NewTimeoutRWC(conn)
|
socket := wrappers.NewTimeoutRWC(conn, conf.PublicIPv4, conf.PublicIPv6)
|
||||||
socket = wrappers.NewStreamCipherRWC(socket, obfs2.Encryptor, obfs2.Decryptor)
|
socket = wrappers.NewStreamCipherRWC(socket, obfs2.Encryptor, obfs2.Decryptor)
|
||||||
|
|
||||||
return connOpts, socket, nil
|
return connOpts, socket, nil
|
||||||
|
|||||||
+14
-21
@@ -59,16 +59,6 @@ func (c *Config) BindAddr() string {
|
|||||||
return getAddr(c.BindIP, c.BindPort)
|
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.
|
// StatAddr returns connection string to the stats API.
|
||||||
func (c *Config) StatAddr() string {
|
func (c *Config) StatAddr() string {
|
||||||
return getAddr(c.StatsIP, c.StatsPort)
|
return getAddr(c.StatsIP, c.StatsPort)
|
||||||
@@ -76,10 +66,15 @@ func (c *Config) StatAddr() string {
|
|||||||
|
|
||||||
// GetURLs returns configured IPURLs instance with links to this server.
|
// GetURLs returns configured IPURLs instance with links to this server.
|
||||||
func (c *Config) GetURLs() IPURLs {
|
func (c *Config) GetURLs() IPURLs {
|
||||||
return IPURLs{
|
urls := IPURLs{}
|
||||||
IPv4: getURLs(c.PublicIPv4, c.PublicIPv4Port, c.Secret),
|
if c.PublicIPv4 != nil {
|
||||||
IPv6: getURLs(c.PublicIPv6, c.PublicIPv6Port, c.Secret),
|
urls.IPv4 = getURLs(c.PublicIPv4, c.PublicIPv4Port, c.Secret)
|
||||||
}
|
}
|
||||||
|
if c.PublicIPv6 != nil {
|
||||||
|
urls.IPv6 = getURLs(c.PublicIPv6, c.PublicIPv6Port, c.Secret)
|
||||||
|
}
|
||||||
|
|
||||||
|
return urls
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAddr(host fmt.Stringer, port uint16) string {
|
func getAddr(host fmt.Stringer, port uint16) string {
|
||||||
@@ -106,12 +101,11 @@ func NewConfig(debug, verbose bool, // nolint: gocyclo
|
|||||||
if publicIPv4 == nil {
|
if publicIPv4 == nil {
|
||||||
publicIPv4, err = getGlobalIPv4()
|
publicIPv4, err = getGlobalIPv4()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("Cannot get public IP")
|
publicIPv4 = nil
|
||||||
|
} else if publicIPv4.To4() == nil {
|
||||||
|
return nil, errors.Errorf("IP %s is not IPv4", publicIPv4.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if publicIPv4.To4() == nil {
|
|
||||||
return nil, errors.Errorf("IP %s is not IPv4", publicIPv4.String())
|
|
||||||
}
|
|
||||||
if PublicIPv4Port == 0 {
|
if PublicIPv4Port == 0 {
|
||||||
PublicIPv4Port = bindPort
|
PublicIPv4Port = bindPort
|
||||||
}
|
}
|
||||||
@@ -119,12 +113,11 @@ func NewConfig(debug, verbose bool, // nolint: gocyclo
|
|||||||
if publicIPv6 == nil {
|
if publicIPv6 == nil {
|
||||||
publicIPv6, err = getGlobalIPv6()
|
publicIPv6, err = getGlobalIPv6()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
publicIPv6 = publicIPv4
|
publicIPv6 = nil
|
||||||
|
} else if publicIPv6.To4() != nil {
|
||||||
|
return nil, errors.Errorf("IP %s is not IPv6", publicIPv6.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if publicIPv6.To16() == nil {
|
|
||||||
return nil, errors.Errorf("IP %s is not IPv6", publicIPv6.String())
|
|
||||||
}
|
|
||||||
if publicIPv6Port == 0 {
|
if publicIPv6Port == 0 {
|
||||||
publicIPv6Port = bindPort
|
publicIPv6Port = bindPort
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
@@ -15,7 +16,8 @@ import (
|
|||||||
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
||||||
|
|
||||||
"github.com/9seconds/mtg/config"
|
"github.com/9seconds/mtg/config"
|
||||||
"github.com/9seconds/mtg/proxy"
|
"github.com/9seconds/mtg/mtproto"
|
||||||
|
"github.com/9seconds/mtg/telegram"
|
||||||
"github.com/juju/errors"
|
"github.com/juju/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -112,15 +114,29 @@ func main() {
|
|||||||
atom,
|
atom,
|
||||||
)).Sugar()
|
)).Sugar()
|
||||||
|
|
||||||
stat := proxy.NewStats(conf)
|
tg := telegram.NewMiddleTelegram(conf, logger)
|
||||||
go stat.Serve()
|
connOpts := &mtproto.ConnectionOpts{
|
||||||
|
DC: int16(1),
|
||||||
srv := proxy.NewServer(conf, logger, stat)
|
ConnectionType: mtproto.ConnectionTypeAbridged,
|
||||||
printURLs(conf.GetURLs())
|
ConnectionProto: mtproto.ConnectionProtocolIPv4,
|
||||||
|
|
||||||
if err := srv.Serve(); err != nil {
|
|
||||||
logger.Fatal(err.Error())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sock, err := tg.Dial(connOpts)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
_, err = tg.Init(connOpts, sock)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
// stat := proxy.NewStats(conf)
|
||||||
|
// go stat.Serve()
|
||||||
|
|
||||||
|
// srv := proxy.NewServer(conf, logger, stat)
|
||||||
|
// printURLs(conf.GetURLs())
|
||||||
|
|
||||||
|
// if err := srv.Serve(); err != nil {
|
||||||
|
// logger.Fatal(err.Error())
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
func setRLimit() (err error) {
|
func setRLimit() (err error) {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package mtproto
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"net"
|
|
||||||
|
|
||||||
"github.com/juju/errors"
|
"github.com/juju/errors"
|
||||||
)
|
)
|
||||||
@@ -19,7 +18,8 @@ type ConnectionOpts struct {
|
|||||||
DC int16
|
DC int16
|
||||||
ConnectionType ConnectionType
|
ConnectionType ConnectionType
|
||||||
ConnectionProto ConnectionProtocol
|
ConnectionProto ConnectionProtocol
|
||||||
ClientAddr *net.TCPAddr
|
QuickAck bool
|
||||||
|
SimpleAck bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Different connection types which user requests from Telegram.
|
// Different connection types which user requests from Telegram.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package rpc
|
package rpc
|
||||||
|
|
||||||
import "bytes"
|
import (
|
||||||
|
"bytes"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
rpcHandshakeTagLength = 4
|
rpcHandshakeTagLength = 4
|
||||||
|
|||||||
@@ -22,11 +22,12 @@ const (
|
|||||||
|
|
||||||
var emptyIP = [4]byte{0x00, 0x00, 0x00, 0x00}
|
var emptyIP = [4]byte{0x00, 0x00, 0x00, 0x00}
|
||||||
|
|
||||||
func NewMiddleProxyCipherRWC(conn wrappers.ReadWriteCloserWithAddr, req *rpc.RPCNonceRequest,
|
func NewMiddleProxyCipherRWC(conn wrappers.ReadWriteCloserWithAddr, req *rpc.RPCNonceRequest, resp *rpc.RPCNonceResponse, secret []byte) wrappers.ReadWriteCloserWithAddr {
|
||||||
resp *rpc.RPCNonceResponse, client *net.TCPAddr, secret []byte) wrappers.ReadWriteCloserWithAddr {
|
localAddr := conn.LocalAddr()
|
||||||
remote := conn.Addr()
|
remoteAddr := conn.RemoteAddr()
|
||||||
encKey, encIV := makeKeys(CipherPurposeClient, req, resp, client, remote, secret)
|
|
||||||
decKey, decIV := makeKeys(CipherPurposeServer, req, resp, client, remote, secret)
|
encKey, encIV := makeKeys(CipherPurposeClient, req, resp, localAddr, remoteAddr, secret)
|
||||||
|
decKey, decIV := makeKeys(CipherPurposeServer, req, resp, localAddr, remoteAddr, secret)
|
||||||
|
|
||||||
enc, _ := makeEncrypterDecrypter(encKey, encIV)
|
enc, _ := makeEncrypterDecrypter(encKey, encIV)
|
||||||
_, dec := makeEncrypterDecrypter(decKey, decIV)
|
_, dec := makeEncrypterDecrypter(decKey, decIV)
|
||||||
|
|||||||
@@ -112,8 +112,12 @@ func (f *FrameRWC) Close() error {
|
|||||||
return f.conn.Close()
|
return f.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FrameRWC) Addr() *net.TCPAddr {
|
func (f *FrameRWC) LocalAddr() *net.TCPAddr {
|
||||||
return f.conn.Addr()
|
return f.conn.LocalAddr()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FrameRWC) RemoteAddr() *net.TCPAddr {
|
||||||
|
return f.conn.RemoteAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFrameRWC(conn wrappers.ReadWriteCloserWithAddr, seqNo int32) wrappers.ReadWriteCloserWithAddr {
|
func NewFrameRWC(conn wrappers.ReadWriteCloserWithAddr, seqNo int32) wrappers.ReadWriteCloserWithAddr {
|
||||||
|
|||||||
+3
-1
@@ -14,6 +14,8 @@ const telegramDialTimeout = 10 * time.Second
|
|||||||
|
|
||||||
type tgDialer struct {
|
type tgDialer struct {
|
||||||
net.Dialer
|
net.Dialer
|
||||||
|
|
||||||
|
conf *config.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *tgDialer) dial(addr string) (net.Conn, error) {
|
func (t *tgDialer) dial(addr string) (net.Conn, error) {
|
||||||
@@ -34,5 +36,5 @@ func (t *tgDialer) dialRWC(addr string) (wrappers.ReadWriteCloserWithAddr, error
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return wrappers.NewTimeoutRWC(conn), nil
|
return wrappers.NewTimeoutRWC(conn, t.conf.PublicIPv4, t.conf.PublicIPv6), nil
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -57,7 +57,10 @@ func (t *directTelegram) Init(connOpts *mtproto.ConnectionOpts, conn wrappers.Re
|
|||||||
// to Telegram bypassing middleproxies.
|
// to Telegram bypassing middleproxies.
|
||||||
func NewDirectTelegram(conf *config.Config) Telegram {
|
func NewDirectTelegram(conf *config.Config) Telegram {
|
||||||
return &directTelegram{baseTelegram{
|
return &directTelegram{baseTelegram{
|
||||||
dialer: tgDialer{net.Dialer{Timeout: telegramDialTimeout}},
|
dialer: tgDialer{
|
||||||
|
Dialer: net.Dialer{Timeout: telegramDialTimeout},
|
||||||
|
conf: conf,
|
||||||
|
},
|
||||||
v4Addresses: directV4Addresses,
|
v4Addresses: directV4Addresses,
|
||||||
v6Addresses: directV6Addresses,
|
v6Addresses: directV6Addresses,
|
||||||
}}
|
}}
|
||||||
|
|||||||
+7
-3
@@ -1,6 +1,7 @@
|
|||||||
package telegram
|
package telegram
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -24,7 +25,10 @@ func NewMiddleTelegram(conf *config.Config, logger *zap.SugaredLogger) Telegram
|
|||||||
tg := &middleTelegram{
|
tg := &middleTelegram{
|
||||||
middleTelegramCaller: middleTelegramCaller{
|
middleTelegramCaller: middleTelegramCaller{
|
||||||
baseTelegram: baseTelegram{
|
baseTelegram: baseTelegram{
|
||||||
dialer: tgDialer{net.Dialer{Timeout: telegramDialTimeout}},
|
dialer: tgDialer{
|
||||||
|
Dialer: net.Dialer{Timeout: telegramDialTimeout},
|
||||||
|
conf: conf,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
logger: logger,
|
logger: logger,
|
||||||
httpClient: &http.Client{
|
httpClient: &http.Client{
|
||||||
@@ -54,8 +58,7 @@ func (t *middleTelegram) Init(connOpts *mtproto.ConnectionOpts, conn wrappers.Re
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
secureConn := mtwrappers.NewMiddleProxyCipherRWC(conn, rpcNonceReq,
|
secureConn := mtwrappers.NewMiddleProxyCipherRWC(conn, rpcNonceReq, rpcNonceResp, t.proxySecret)
|
||||||
rpcNonceResp, connOpts.ClientAddr, t.proxySecret)
|
|
||||||
secureConn = mtwrappers.NewFrameRWC(secureConn, rpc.RPCHandshakeSeqNo)
|
secureConn = mtwrappers.NewFrameRWC(secureConn, rpc.RPCHandshakeSeqNo)
|
||||||
|
|
||||||
rpcHandshakeReq, err := t.sendRPCHandshakeRequest(secureConn)
|
rpcHandshakeReq, err := t.sendRPCHandshakeRequest(secureConn)
|
||||||
@@ -123,6 +126,7 @@ func (t *middleTelegram) receiveRPCHandshakeResponse(conn io.Reader, req *rpc.RP
|
|||||||
if err = rpcHandshakeResp.Valid(req); err != nil {
|
if err = rpcHandshakeResp.Valid(req); err != nil {
|
||||||
return nil, errors.Annotate(err, "Invalid RPC handshake response")
|
return nil, errors.Annotate(err, "Invalid RPC handshake response")
|
||||||
}
|
}
|
||||||
|
fmt.Println("VICTORY")
|
||||||
|
|
||||||
return rpcHandshakeResp, nil
|
return rpcHandshakeResp, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ func (c *BlockCipherReadWriteCloserWithAddr) Read(p []byte) (int, error) {
|
|||||||
return errors.Annotate(err, "Cannot read from socket")
|
return errors.Annotate(err, "Cannot read from socket")
|
||||||
}
|
}
|
||||||
c.Buffer.Write(p[:n])
|
c.Buffer.Write(p[:n])
|
||||||
|
bufferLength = c.Buffer.Len()
|
||||||
}
|
}
|
||||||
c.decryptor.CryptBlocks(c.Buffer.Bytes(), c.Buffer.Bytes())
|
c.decryptor.CryptBlocks(c.Buffer.Bytes(), c.Buffer.Bytes())
|
||||||
|
|
||||||
@@ -47,8 +48,12 @@ func (c *BlockCipherReadWriteCloserWithAddr) Close() error {
|
|||||||
return c.conn.Close()
|
return c.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *BlockCipherReadWriteCloserWithAddr) Addr() *net.TCPAddr {
|
func (c *BlockCipherReadWriteCloserWithAddr) LocalAddr() *net.TCPAddr {
|
||||||
return c.conn.Addr()
|
return c.conn.LocalAddr()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *BlockCipherReadWriteCloserWithAddr) RemoteAddr() *net.TCPAddr {
|
||||||
|
return c.conn.RemoteAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBlockCipherRWC(conn ReadWriteCloserWithAddr, encryptor, decryptor cipher.BlockMode) ReadWriteCloserWithAddr {
|
func NewBlockCipherRWC(conn ReadWriteCloserWithAddr, encryptor, decryptor cipher.BlockMode) ReadWriteCloserWithAddr {
|
||||||
|
|||||||
+6
-2
@@ -48,8 +48,12 @@ func (c *CtxReadWriteCloserWithAddr) Close() error {
|
|||||||
return c.conn.Close()
|
return c.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CtxReadWriteCloserWithAddr) Addr() *net.TCPAddr {
|
func (c *CtxReadWriteCloserWithAddr) LocalAddr() *net.TCPAddr {
|
||||||
return c.conn.Addr()
|
return c.conn.LocalAddr()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CtxReadWriteCloserWithAddr) RemoteAddr() *net.TCPAddr {
|
||||||
|
return c.conn.RemoteAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCtxRWC returns ReadWriteCloser which respects given context,
|
// NewCtxRWC returns ReadWriteCloser which respects given context,
|
||||||
|
|||||||
+6
-2
@@ -36,8 +36,12 @@ func (l *LogReadWriteCloserWithAddr) Close() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LogReadWriteCloserWithAddr) Addr() *net.TCPAddr {
|
func (l *LogReadWriteCloserWithAddr) LocalAddr() *net.TCPAddr {
|
||||||
return l.conn.Addr()
|
return l.conn.LocalAddr()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *LogReadWriteCloserWithAddr) RemoteAddr() *net.TCPAddr {
|
||||||
|
return l.conn.RemoteAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLogRWC wraps ReadWriteCloser with logger calls.
|
// NewLogRWC wraps ReadWriteCloser with logger calls.
|
||||||
|
|||||||
+2
-1
@@ -8,5 +8,6 @@ import (
|
|||||||
type ReadWriteCloserWithAddr interface {
|
type ReadWriteCloserWithAddr interface {
|
||||||
io.ReadWriteCloser
|
io.ReadWriteCloser
|
||||||
|
|
||||||
Addr() *net.TCPAddr
|
LocalAddr() *net.TCPAddr
|
||||||
|
RemoteAddr() *net.TCPAddr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,8 +43,12 @@ func (c *StreamCipherReadWriteCloserWithAddr) Close() error {
|
|||||||
return c.conn.Close()
|
return c.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *StreamCipherReadWriteCloserWithAddr) Addr() *net.TCPAddr {
|
func (c *StreamCipherReadWriteCloserWithAddr) LocalAddr() *net.TCPAddr {
|
||||||
return c.conn.Addr()
|
return c.conn.LocalAddr()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *StreamCipherReadWriteCloserWithAddr) RemoteAddr() *net.TCPAddr {
|
||||||
|
return c.conn.RemoteAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStreamCipherRWC returns wrapper which transparently
|
// NewStreamCipherRWC returns wrapper which transparently
|
||||||
|
|||||||
+25
-4
@@ -8,7 +8,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type TimeoutReadWriteCloserWithAddr struct {
|
type TimeoutReadWriteCloserWithAddr struct {
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
|
publicIPv4 net.IP
|
||||||
|
publicIPv6 net.IP
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TimeoutReadWriteCloserWithAddr) Read(p []byte) (int, error) {
|
func (t *TimeoutReadWriteCloserWithAddr) Read(p []byte) (int, error) {
|
||||||
@@ -25,10 +27,29 @@ func (t *TimeoutReadWriteCloserWithAddr) Close() error {
|
|||||||
return t.conn.Close()
|
return t.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TimeoutReadWriteCloserWithAddr) Addr() *net.TCPAddr {
|
func (t *TimeoutReadWriteCloserWithAddr) RemoteAddr() *net.TCPAddr {
|
||||||
return t.conn.RemoteAddr().(*net.TCPAddr)
|
return t.conn.RemoteAddr().(*net.TCPAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTimeoutRWC(conn net.Conn) ReadWriteCloserWithAddr {
|
func (t *TimeoutReadWriteCloserWithAddr) LocalAddr() *net.TCPAddr {
|
||||||
return &TimeoutReadWriteCloserWithAddr{conn}
|
addr := t.conn.LocalAddr().(*net.TCPAddr)
|
||||||
|
newAddr := *addr
|
||||||
|
|
||||||
|
if t.RemoteAddr().IP.To4() != nil {
|
||||||
|
if t.publicIPv4 != nil {
|
||||||
|
newAddr.IP = t.publicIPv4
|
||||||
|
}
|
||||||
|
} else if t.publicIPv6 != nil {
|
||||||
|
newAddr.IP = t.publicIPv6
|
||||||
|
}
|
||||||
|
|
||||||
|
return &newAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTimeoutRWC(conn net.Conn, ipv4, ipv6 net.IP) ReadWriteCloserWithAddr {
|
||||||
|
return &TimeoutReadWriteCloserWithAddr{
|
||||||
|
conn: conn,
|
||||||
|
publicIPv4: ipv4,
|
||||||
|
publicIPv6: ipv6,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,12 @@ func (t *TrafficReadWriteCloserWithAddr) Close() error {
|
|||||||
return t.conn.Close()
|
return t.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TrafficReadWriteCloserWithAddr) Addr() *net.TCPAddr {
|
func (t *TrafficReadWriteCloserWithAddr) LocalAddr() *net.TCPAddr {
|
||||||
return t.conn.Addr()
|
return t.conn.LocalAddr()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TrafficReadWriteCloserWithAddr) RemoteAddr() *net.TCPAddr {
|
||||||
|
return t.conn.RemoteAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTrafficRWC wraps ReadWriteCloser to have read/write callbacks.
|
// NewTrafficRWC wraps ReadWriteCloser to have read/write callbacks.
|
||||||
|
|||||||
Reference in New Issue
Block a user