Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package wrappers
  2. import (
  3. "net"
  4. "time"
  5. "go.uber.org/zap"
  6. )
  7. type ConnPurpose uint8
  8. func (c ConnPurpose) String() string {
  9. switch c {
  10. case ConnPurposeClient:
  11. return "client"
  12. case ConnPurposeTelegram:
  13. return "telegram"
  14. }
  15. return ""
  16. }
  17. const (
  18. ConnPurposeClient = iota
  19. ConnPurposeTelegram
  20. )
  21. const (
  22. connTimeoutRead = 5 * time.Minute
  23. connTimeoutWrite = 5 * time.Minute
  24. )
  25. type Conn struct {
  26. connID string
  27. conn net.Conn
  28. logger *zap.SugaredLogger
  29. publicIPv4 net.IP
  30. publicIPv6 net.IP
  31. }
  32. func (c *Conn) Write(p []byte) (int, error) {
  33. c.conn.SetWriteDeadline(time.Now().Add(connTimeoutWrite))
  34. n, err := c.conn.Write(p)
  35. c.logger.Debugw("Write to stream", "bytes", n, "error", err)
  36. return n, err
  37. }
  38. func (c *Conn) Read(p []byte) (int, error) {
  39. c.conn.SetReadDeadline(time.Now().Add(connTimeoutRead))
  40. n, err := c.conn.Read(p)
  41. c.logger.Debugw("Read from stream", "bytes", n, "error", err)
  42. return n, err
  43. }
  44. func (c *Conn) Close() error {
  45. defer c.logger.Debugw("Closed connection")
  46. return c.conn.Close()
  47. }
  48. func (c *Conn) LocalAddr() *net.TCPAddr {
  49. addr := c.conn.LocalAddr().(*net.TCPAddr)
  50. newAddr := *addr
  51. if c.RemoteAddr().IP.To4() != nil {
  52. if c.publicIPv4 != nil {
  53. newAddr.IP = c.publicIPv4
  54. }
  55. } else if c.publicIPv6 != nil {
  56. newAddr.IP = c.publicIPv6
  57. }
  58. return &newAddr
  59. }
  60. func (c *Conn) RemoteAddr() *net.TCPAddr {
  61. return c.conn.RemoteAddr().(*net.TCPAddr)
  62. }
  63. func (c *Conn) Logger() *zap.SugaredLogger {
  64. return c.logger
  65. }
  66. func NewConn(conn net.Conn, connID string, purpose ConnPurpose, publicIPv4, publicIPv6 net.IP) StreamReadWriteCloser {
  67. logger := zap.S().With(
  68. "connection_id", connID,
  69. "local_address", conn.LocalAddr(),
  70. "remote_address", conn.RemoteAddr(),
  71. "purpose", purpose,
  72. ).Named("conn")
  73. wrapper := Conn{
  74. logger: logger,
  75. connID: connID,
  76. conn: conn,
  77. publicIPv4: publicIPv4,
  78. publicIPv6: publicIPv6,
  79. }
  80. wrapper.logger = logger.With("faked_local_addr", wrapper.LocalAddr())
  81. return &wrapper
  82. }