// GetFileRecordPeerList returns a compact peer list containing IP/port pairs func (db *dbw) GetFileRecordPeerList(infohash, exclude string, limit int) ([]byte, error) { // Get IP and port of all peers who are active and seeding this file query := `SELECT DISTINCT announce_log.ip,announce_log.port FROM announce_log JOIN files ON announce_log.info_hash = files.info_hash JOIN files_users ON files.id = files_users.file_id AND announce_log.ip = files_users.ip WHERE files_users.active=1 AND files.info_hash=? AND announce_log.ip != ? LIMIT ?;` result := struct { IP string Port uint16 }{"", 0} rows, err := db.Queryx(query, infohash, exclude, limit) if err != nil && err != sql.ErrNoRows { return nil, err } // Buffer for compact list buf := make([]byte, 0) for rows.Next() { if err = rows.StructScan(&result); err != nil { log.Println(err.Error()) break } buf = append(buf, common.IP2B(result.IP, result.Port)...) } return buf, nil }
// GetFileRecordPeerList returns a compact peer list containing IP/port pairs func (db *qlw) GetFileRecordPeerList(infohash, exclude string, limit int) ([]byte, error) { rs, _, err := qlQuery(db, "fileuser_find_peerlist", true, infohash, exclude) buf := []byte{} if err == nil && len(rs) > 0 { err = rs[0].Do(false, func(data []interface{}) (bool, error) { buf = append(buf, common.IP2B(data[0].(string), uint16(data[1].(int32)))...) return len(buf)/6 < limit, nil }) } return buf, err }
// MarshalBinary creates a packed byte array from a AnnounceResponse func (u AnnounceResponse) MarshalBinary() ([]byte, error) { res := bytes.NewBuffer(make([]byte, 0)) // Action (uint32, must be 1 for announce) if u.Action != uint32(1) { return nil, fmt.Errorf("invalid action '%d' for AnnounceResponse", u.Action) } if err := binary.Write(res, binary.BigEndian, u.Action); err != nil { return nil, err } // TransID (uint32) if err := binary.Write(res, binary.BigEndian, u.TransID); err != nil { return nil, err } // Interval (uint32) if err := binary.Write(res, binary.BigEndian, u.Interval); err != nil { return nil, err } // Leechers (uint32) if err := binary.Write(res, binary.BigEndian, u.Leechers); err != nil { return nil, err } // Seeders (uint32) if err := binary.Write(res, binary.BigEndian, u.Seeders); err != nil { return nil, err } // PeerList, []compactPeer, iterated and compressed to compact format for _, peer := range u.PeerList { // Compact and write if err := binary.Write(res, binary.BigEndian, common.IP2B(peer.IP, peer.Port)); err != nil { return nil, err } } return res.Bytes(), nil }