func NewTorrent(clientId ClientId, port int, torrent string, downloadPath string) *Torrent { t := new(Torrent) t.ClientId = clientId t.Port = port t.DownloadPath = downloadPath t.Downloaded = 0 t.Uploaded = 0 t.IsComplete = false metaInfo := readTorrent(torrent) t.Announce = metaInfo.Announce t.InfoHash = metaInfo.InfoHash t.CreationDate = metaInfo.CreationDate t.Name = metaInfo.Info.Name t.Length = metaInfo.Info.Length t.PieceHashes = metaInfo.Info.Pieces t.PieceLength = metaInfo.Info.PieceLength t.PieceCount = t.Length / t.PieceLength t.BitField = bitarray.New(t.PieceCount) t.Tracker = NewTracker(t.Announce) log.Debugf("File Length: %v", t.Length) log.Debugf("Piece Length: %v", t.PieceLength) log.Debugf("Piece Count: %v", t.PieceCount) return t }
func test(peer *Peer, torrent *Torrent) (err error) { log.Debugf("Fired!") err = peer.Connect() if err != nil || peer.Conn == nil { return } err = peer.SendHandshake(torrent.InfoHash, string(torrent.ClientId)) if err != nil { log.Errorf("%v", err) } err = peer.SendUnchoke() if err != nil { log.Errorf("%v", err) } err = peer.SendInterested() if err != nil { log.Errorf("%v", err) } err = peer.RequestBlock(300, 0, uint32(PieceChunkLenght)) if err != nil { log.Errorf("%v", err) } err = peer.ReadHandshake() log.Debugf("Receiving Data...") err = peer.ReceiveData() if err != nil { log.Errorf("%v", err) } peer.ParseData() return }
func (peer *Peer) Connect() (err error) { log.Debugf("Connecting to %s...", peer.Addr.String()) peer.Conn, err = net.DialTimeout("tcp", peer.Addr.String(), time.Second*5) if peer.Conn == nil || err != nil { log.Debugf("Unable to connect to %s", peer.Addr.String()) } log.Debugf("Connected to %s", peer.Addr.String()) return }
func (tracker Tracker) Peers(infoHash string, clientId ClientId, port, uploaded, downloaded, left int) (trackerResponse *TrackerResponse, err error) { v := url.Values{} v.Set("info_hash", infoHash) v.Add("peer_id", string(clientId)) v.Add("port", strconv.FormatInt(int64(port), 10)) v.Add("uploaded", strconv.FormatInt(int64(uploaded), 10)) v.Add("downloaded", strconv.FormatInt(int64(downloaded), 10)) v.Add("left", strconv.FormatInt(int64(left), 10)) v.Add("compact", strconv.FormatInt(1, 10)) query := v.Encode() uri := tracker.Announce + "?" + query log.Debugf("Contacting: %v", tracker.Announce) log.Debugf("%v", uri) httpResp, err := http.Get(uri) defer func() { if err := httpResp.Body.Close(); err != nil { return } }() if err != nil { return } if httpResp.StatusCode != 200 { //buf := new(bytes.Buffer) //buf.ReadFrom(resp.Body) //response := buf.String() err = fmt.Errorf("Unable to contact the tracker. Status code: %v", httpResp.StatusCode) return } trackerResponse = new(TrackerResponse) err = bencode.Unmarshal(httpResp.Body, trackerResponse) if err != nil { return } trackerResponse.PeerAddresses, err = parsePeerAddresses(trackerResponse.BinaryPeers) if err != nil { return } return }
// querySync - do an gsnmp library sync_* query // // Results are returned in C form, use convertResults() to convert to a Go struct. func querySync(session *_Ctype_GNetSnmp, vbl *_Ctype_GList, uritype _Ctype_GNetSnmpUriType, version SnmpVersion) (*_Ctype_GList, error) { var gerror *C.GError var out *_Ctype_GList if Debug { applog.Debugf("Starting a %s", uritype) } switch UriType(uritype) { case GNET_SNMP_URI_GET: out = C.gnet_snmp_sync_get(session, vbl, &gerror) case GNET_SNMP_URI_NEXT: out = C.gnet_snmp_sync_getnext(session, vbl, &gerror) case GNET_SNMP_URI_WALK: out = C.gnet_snmp_sync_walk(session, vbl, &gerror) /* TODO gnet_snmp_sync_walk is just a series of 'getnexts' if version == GNET_SNMP_V1 { out = C.gnet_snmp_sync_walk(session, vbl, &gerror) } else { // do a proper bulkwalk } */ default: return nil, fmt.Errorf("%s: querySync(): unknown uritype", libname()) } /* Originally error handling was done at this point, like gsnmp-0.3.0/examples/gsnmp-get.c. However in production too many results were being discarded. Hence just return out, and convertResults() will convert any errors in out to nil values. */ return out, nil }
func (torrent *Torrent) UpdatePeers() { trackerResponse, err := torrent.Tracker.Peers( torrent.InfoHash, torrent.ClientId, torrent.Port, torrent.Uploaded, torrent.Downloaded, torrent.Length, ) if err != nil { log.Errorf("Unable to retrieve the peers: %v", err) } addresses := make(map[string]bool) for _, peer := range torrent.Peers { addresses[peer.Addr.String()] = true } for _, peerAddr := range trackerResponse.PeerAddresses { if _, ok := addresses[peerAddr.String()]; !ok { log.Debugf("Found Peer: %v", peerAddr) torrent.AddPeer(peerAddr) } } }
func readTorrent(torrent string) *metainfo.MetaInfo { if strings.HasPrefix(torrent, "http:") { panic("Not implemented") } else if strings.HasPrefix(torrent, "magnet:") { panic("Not implemented") } else { log.Debugf("Opening: %v", torrent) file, err := os.Open(torrent) if err != nil { panic(err) } defer func() { if err := file.Close(); err != nil { panic(err) } }() metaInfo, err := metainfo.Read(file) if err != nil { panic(err) } return metaInfo } }
// Query takes a URI in RFC 4088 format, does an SNMP query and returns the results. func Query(params *QueryParams) (results *llrb.Tree, err error) { parsed_uri, err := parseURI(params.Uri) if Debug { applog.Debugf("parsed_uri: %s\n\n", parsed_uri) } if err != nil { return nil, err } path := C.GoString((*C.char)(parsed_uri.path)) if Debug { applog.Warningf("number of incoming uris: %d", uriCount(path)) } if err := uriCountMaxed(path, MAX_URI_COUNT); err != nil { return nil, err } vbl, uritype, err := parsePath(params.Uri, parsed_uri) defer uriDelete(parsed_uri) if Debug { applog.Debugf("vbl, uritype: %s, %s", gListOidsString(vbl), uritype) } if err != nil { return nil, err } session, err := newUri(params, parsed_uri) /* causing <undefined symbol: gnet_snmp_taddress_get_short_name> if Debug { applog.Warningf("session: %s\n\n", session) } */ if err != nil { return nil, err } vbl_results, err := querySync(session, vbl, uritype, params.Version) defer vblDelete(vbl_results) if err != nil { return nil, err } return convertResults(params, vbl_results), nil }
func (peer *Peer) ReadHandshake() (err error) { buf := make([]byte, messages.HandshakeLength) n, err := peer.Conn.Read(buf) if err != nil || n != messages.HandshakeLength { log.Errorf("Cannot read the handshake: %v", err) return err } var hand messages.Handshake err = binary.Read(bytes.NewBuffer(buf), binary.BigEndian, &hand) if err != nil { log.Errorf("%v", err) } log.Debugf("Handshake from peer %v", peer.Addr.String()) log.Debugf(hand.String()) return err }
func (disp *dispatcher) ServeHTTP(w http.ResponseWriter, req *http.Request) { dispatched := false startTime := time.Now() applog.Infof("Started %s %s", req.Method, req.URL) localPath := path.Join(disp.env.PublicFolder, req.URL.Path) applog.Debugf("Checking for existance of %s", localPath) if info, err := os.Stat(localPath); err == nil { if info.IsDir() { indexPath := path.Join(localPath, "index.html") applog.Debugf("%s is a directory, checking for existance of %s", localPath, indexPath) if _, err := os.Stat(indexPath); err == nil { applog.Debugf("Serving static file %s", indexPath) disp.publicHandler.ServeHTTP(w, req) dispatched = true } } else { applog.Debugf("Serving static file %s", localPath) disp.publicHandler.ServeHTTP(w, req) dispatched = true } } if !dispatched { applog.Debugf("Dispatching %s", req.URL) disp.appHandler.ServeHTTP(w, req) } duration := time.Now().Sub(startTime) applog.Infof("Finished processing %s %s (%s)", req.Method, req.URL, duration.String()) }
func Read(file *os.File) (metaInfo *MetaInfo, err error) { metaInfo = new(MetaInfo) if err = bencode.Unmarshal(file, metaInfo); err != nil { return } if _, err = file.Seek(0, 0); err != nil { return } metaInfo.InfoHash = calculateInfoHash(file) log.Debugf("Info hash: %v", metaInfo.InfoHash) if err != nil { return } return }
func (peer *Peer) ReceiveData() (err error) { nBytes := 0 buf := make([]byte, 65536) for { peer.Conn.SetReadDeadline(time.Now().Add(5 * time.Second)) n, err := peer.Conn.Read(buf) readed := buf[:n] nBytes += n if err == io.EOF || n == 0 { break } if err != nil { log.Errorf("Error in reading: %v", err) return err } peer.Data = append(peer.Data, readed...) } log.Debugf("Readed %v, byte(s)", nBytes) //log.Debugf("%v", peer.Data) return }
func (peer *Peer) ParseData() { for { if len(peer.Data) < 4 { break /*peer.SendUnchoke() peer.SendInterested() log.Debugf("Trying to request piece #%v", i) peer.RequestBlock(300, 0, uint32(PieceChunkLenght)) peer.ReceiveData() i++*/ } var message messages.Message err := binary.Read(bytes.NewBuffer(peer.Data[:4]), binary.BigEndian, &message.Length) if err != nil { panic(err) } if message.Length == 0 { log.Debugf("Keep alive") peer.Data = peer.Data[4:] } else { message.Id = peer.Data[4] data := peer.Data[:4+message.Length] switch message.Id { case messages.ChokeId: log.Debugf("Choke") case messages.UnchokeId: log.Debugf("Unchoke") case messages.InterestedId: log.Debugf("Interested") case messages.NotInterestedId: log.Debugf("NotInterested") case messages.HaveId: var haveMsg messages.Have err = binary.Read(bytes.NewBuffer(data), binary.BigEndian, &haveMsg) log.Debugf("Peer %v - Have piece #%v", peer.Addr.String(), haveMsg.PieceIndex) if haveMsg.PieceIndex > peer.PieceCount { log.Errorf("Invalid piece index, piece index: %v, piece count: %v", haveMsg.PieceIndex, peer.PieceCount) break } peer.BitField.Set(int(haveMsg.PieceIndex), true) log.Debugf("Peer %v - BitField updated", peer.Addr.String()) case messages.BitFieldId: log.Debugf("BitField") var bitMsg messages.BitArray err = binary.Read(bytes.NewBuffer(data), binary.BigEndian, &bitMsg) bitMsg.BitField = data[:message.Length-1] bitCount := (message.Length - 1) * 8 if peer.PieceCount > bitCount { log.Errorf("Invalid BitField, bit count: %v, piece count: %v", bitCount, peer.PieceCount) break } peer.BitField = bitarray.NewFromBytes(bitMsg.BitField, int(peer.PieceCount)) log.Debugf("Peer %v - New BitField:", peer.Addr.String()) case messages.RequestId: log.Debugf("Request") case messages.PieceId: log.Debugf("Piece") var pieceMsg messages.Piece err = binary.Read(bytes.NewBuffer(data), binary.BigEndian, &pieceMsg) pieceMsg.BlockData = data[:message.Length-9] log.Debugf("Peer %v - Found a new block - PieceIndex: %v BlockOffset: %v", peer.Addr.String(), pieceMsg.PieceIndex, pieceMsg.BlockOffset) case messages.CancelId: log.Debugf("Cancel") case messages.PortId: log.Debugf("Port") } peer.Data = peer.Data[4+message.Length:] } } return }