func (c *localNodeClient) Id() (id bittorrent.BTID) { if c.localNode != nil { return c.localNode.Id } // TODO(JB): is this stupid? return bittorrent.BTID(0) }
func (local *localNode) Ping(remote *RemoteNode) (<-chan *bencoding.Dict, <-chan error) { pingResult := make(chan *bencoding.Dict) pingErr := make(chan error) query := local.sendQuery(remote, "ping", bencoding.Dict{}) go func() { defer close(pingResult) defer close(pingErr) select { case value := <-query.Result: remote.Id = bittorrent.BTID((*value)["id"].(bencoding.String)) remote.ConsecutiveFailedQueries = 0 pingResult <- value case err := <-query.Err: remote.ConsecutiveFailedQueries++ pingErr <- err } }() return pingResult, pingErr }
func main() { loggerconfig.Use() if len(os.Args) != 2 { logger.Fatalf("Usage: %v PATH", os.Args[0]) return } weakrand.Seed(time.Now().UTC().UnixNano()) path := os.Args[1] infoDict, err := bittorrent.GenerateTorrentMetaInfo(bittorrent.CreationOptions{ Path: path, PieceLength: PieceLength, ForceMultiFile: false, }) if err != nil { logger.Fatalf("Error generating torrent: %v", err) return } infoData, err := bencoding.Encode(infoDict) if err != nil { logger.Fatalf("Error encoding torrent infodict (for hashing): %v", err) return } torrentDict := bencoding.Dict{ "info": infoDict, "nodes": bencoding.List{ bencoding.List{ bencoding.String("127.0.0.1"), bencoding.Int(6881), }, }, } torrentData, err := bencoding.Encode(torrentDict) if err != nil { logger.Fatalf("Error encoding torrent data: %v", err) return } hasher := sha1.New() hasher.Write(infoData) hash := hasher.Sum(nil) infoHash := bittorrent.BTID(hash) logger.Info("Generated torrent btih=%v.", infoHash) os.Stdout.Write(torrentData) os.Stdout.Sync() }
func localNodeFromBencodingDict(dict bencoding.Dict) (local *localNode) { local = new(localNode) local.Id = bittorrent.BTID(dict["Id"].(bencoding.String)) local.Port = int(dict["Port"].(bencoding.Int)) local.OutstandingQueries = make(map[string]*RpcQuery) local.Nodes = map[string]*RemoteNode{} for _, nodeDict := range dict["Nodes"].(bencoding.List) { remote := RemoteNodeFromBencodingDict(nodeDict.(bencoding.Dict)) local.AddOrGetRemoteNode(remote) } return local }
func (local *localNode) decodeNodesString(nodesData bencoding.String, source *RemoteNode) ([]*RemoteNode, error) { result := make([]*RemoteNode, 0) for offset := 0; offset < len(nodesData); offset += nodeContactInfoLen { nodeId := nodesData[offset : offset+nodeContactInfoIdLen] nodeAddress := decodeNodeAddress(nodesData[offset+nodeContactInfoIdLen : offset+nodeContactInfoLen]) resultRemote := RemoteNodeFromAddress(nodeAddress) resultRemote.Source = source resultRemote.Id = bittorrent.BTID(nodeId) resultRemote = local.AddOrGetRemoteNode(resultRemote) result = append(result, resultRemote) } return result, nil }