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.

sockopts.go 2.0KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package network
  2. import (
  3. "fmt"
  4. "net"
  5. "golang.org/x/sys/unix"
  6. )
  7. // SetClientSocketOptions tunes a TCP socket that represents a connection to
  8. // end user (not Telegram service or fronting domain).
  9. func SetClientSocketOptions(conn net.Conn, bufferSize int) error {
  10. tcpConn := conn.(*net.TCPConn) // nolint: forcetypeassert
  11. if err := tcpConn.SetNoDelay(false); err != nil {
  12. return fmt.Errorf("cannot disable TCP_NO_DELAY: %w", err)
  13. }
  14. return setCommonSocketOptions(tcpConn, bufferSize)
  15. }
  16. // SetServerSocketOptions tunes a TCP socket that represents a connection to
  17. // remote server like Telegram or fronting domain (but not end user).
  18. func SetServerSocketOptions(conn net.Conn, bufferSize int) error {
  19. tcpConn := conn.(*net.TCPConn) // nolint: forcetypeassert
  20. if err := tcpConn.SetNoDelay(true); err != nil {
  21. return fmt.Errorf("cannot enable TCP_NO_DELAY: %w", err)
  22. }
  23. return setCommonSocketOptions(tcpConn, bufferSize)
  24. }
  25. func setCommonSocketOptions(conn *net.TCPConn, bufferSize int) error {
  26. if err := conn.SetReadBuffer(bufferSize); err != nil {
  27. return fmt.Errorf("cannot set read buffer size: %w", err)
  28. }
  29. if err := conn.SetWriteBuffer(bufferSize); err != nil {
  30. return fmt.Errorf("cannot set write buffer size: %w", err)
  31. }
  32. if err := conn.SetKeepAlive(false); err != nil {
  33. return fmt.Errorf("cannot disable TCP keepalive probes: %w", err)
  34. }
  35. if err := conn.SetLinger(tcpLingerTimeout); err != nil {
  36. return fmt.Errorf("cannot set TCP linger timeout: %w", err)
  37. }
  38. rawConn, err := conn.SyscallConn()
  39. if err != nil {
  40. return fmt.Errorf("cannot get underlying raw connection")
  41. }
  42. rawConn.Control(func(fd uintptr) { // nolint: errcheck
  43. err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1)
  44. if err != nil {
  45. err = fmt.Errorf("cannot set SO_REUSEADDR: %w", err)
  46. return
  47. }
  48. err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1)
  49. if err != nil {
  50. err = fmt.Errorf("cannot set SO_REUSEPORT: %w", err)
  51. }
  52. })
  53. return nil
  54. }