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
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

proxy_request.go 2.3KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package rpc
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "encoding/binary"
  6. "net"
  7. "github.com/juju/errors"
  8. "github.com/9seconds/mtg/mtproto"
  9. )
  10. type ProxyRequest struct {
  11. Flags proxyRequestFlags
  12. ConnectionID []byte
  13. OurIPPort []byte
  14. ClientIPPort []byte
  15. ADTag []byte
  16. Options *mtproto.ConnectionOpts
  17. }
  18. func (r *ProxyRequest) MakeHeader(message []byte) *bytes.Buffer {
  19. bufferLength := len(TagProxyRequest) +
  20. 4 + // len(flags)
  21. len(r.ConnectionID) +
  22. len(r.ClientIPPort) +
  23. len(r.OurIPPort) +
  24. len(ProxyRequestExtraSize) +
  25. len(ProxyRequestProxyTag) +
  26. 1 + // len(AdTag)
  27. len(r.ADTag)
  28. bufferLength += bufferLength % 4
  29. buf := &bytes.Buffer{}
  30. buf.Grow(bufferLength)
  31. flags := r.Flags
  32. if r.Options.ReadHacks.QuickAck {
  33. flags |= proxyRequestFlagsQuickAck
  34. }
  35. if bytes.HasPrefix(message, proxyRequestFlagsEncryptedPrefix[:]) {
  36. flags |= proxyRequestFlagsEncrypted
  37. }
  38. buf.Write(TagProxyRequest)
  39. buf.Write(flags.Bytes())
  40. buf.Write(r.ConnectionID)
  41. buf.Write(r.ClientIPPort)
  42. buf.Write(r.OurIPPort)
  43. buf.Write(ProxyRequestExtraSize)
  44. buf.Write(ProxyRequestProxyTag)
  45. buf.WriteByte(byte(len(r.ADTag)))
  46. buf.Write(r.ADTag)
  47. buf.Write(make([]byte, (4-buf.Len()%4)%4))
  48. return buf
  49. }
  50. func NewProxyRequest(clientAddr, ownAddr *net.TCPAddr, opts *mtproto.ConnectionOpts, adTag []byte) (*ProxyRequest, error) {
  51. flags := proxyRequestFlagsHasAdTag | proxyRequestFlagsMagic | proxyRequestFlagsExtMode2
  52. switch opts.ConnectionType {
  53. case mtproto.ConnectionTypeAbridged:
  54. flags |= proxyRequestFlagsAbdridged
  55. case mtproto.ConnectionTypeIntermediate:
  56. flags |= proxyRequestFlagsIntermediate
  57. }
  58. request := &ProxyRequest{
  59. Flags: flags,
  60. ADTag: adTag,
  61. Options: opts,
  62. ConnectionID: make([]byte, 8),
  63. ClientIPPort: make([]byte, 16+4),
  64. OurIPPort: make([]byte, 16+4),
  65. }
  66. if _, err := rand.Read(request.ConnectionID); err != nil {
  67. return nil, errors.Annotate(err, "Cannot generate connection ID")
  68. }
  69. port := [4]byte{}
  70. copy(request.ClientIPPort[:16], clientAddr.IP.To16())
  71. binary.LittleEndian.PutUint32(port[:], uint32(clientAddr.Port))
  72. copy(request.ClientIPPort[16:], port[:])
  73. copy(request.OurIPPort[:16], ownAddr.IP.To16())
  74. binary.LittleEndian.PutUint32(port[:], uint32(ownAddr.Port))
  75. copy(request.OurIPPort[16:], port[:])
  76. return request, nil
  77. }