protocol.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package httpTracker
  2. import (
  3. "fmt"
  4. "github.com/anacrolix/dht/v2/krpc"
  5. "github.com/anacrolix/torrent/bencode"
  6. )
  7. type HttpResponse struct {
  8. FailureReason string `bencode:"failure reason"`
  9. Interval int32 `bencode:"interval"`
  10. TrackerId string `bencode:"tracker id"`
  11. Complete int32 `bencode:"complete"`
  12. Incomplete int32 `bencode:"incomplete"`
  13. Peers Peers `bencode:"peers"`
  14. // BEP 7
  15. Peers6 krpc.CompactIPv6NodeAddrs `bencode:"peers6"`
  16. }
  17. type Peers struct {
  18. List []Peer
  19. Compact bool
  20. }
  21. func (me Peers) MarshalBencode() ([]byte, error) {
  22. if me.Compact {
  23. cnas := make([]krpc.NodeAddr, 0, len(me.List))
  24. for _, peer := range me.List {
  25. cnas = append(cnas, krpc.NodeAddr{
  26. IP: peer.IP,
  27. Port: peer.Port,
  28. })
  29. }
  30. return krpc.CompactIPv4NodeAddrs(cnas).MarshalBencode()
  31. } else {
  32. return bencode.Marshal(me.List)
  33. }
  34. }
  35. var (
  36. _ bencode.Unmarshaler = (*Peers)(nil)
  37. _ bencode.Marshaler = Peers{}
  38. )
  39. func (me *Peers) UnmarshalBencode(b []byte) (err error) {
  40. var _v interface{}
  41. err = bencode.Unmarshal(b, &_v)
  42. if err != nil {
  43. return
  44. }
  45. switch v := _v.(type) {
  46. case string:
  47. vars.Add("http responses with string peers", 1)
  48. var cnas krpc.CompactIPv4NodeAddrs
  49. err = cnas.UnmarshalBinary([]byte(v))
  50. if err != nil {
  51. return
  52. }
  53. me.Compact = true
  54. for _, cp := range cnas {
  55. me.List = append(me.List, Peer{
  56. IP: cp.IP[:],
  57. Port: cp.Port,
  58. })
  59. }
  60. return
  61. case []interface{}:
  62. vars.Add("http responses with list peers", 1)
  63. me.Compact = false
  64. for _, i := range v {
  65. var p Peer
  66. p.FromDictInterface(i.(map[string]interface{}))
  67. me.List = append(me.List, p)
  68. }
  69. return
  70. default:
  71. vars.Add("http responses with unhandled peers type", 1)
  72. err = fmt.Errorf("unsupported type: %T", _v)
  73. return
  74. }
  75. }