Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}
Beispiel #4
0
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
}
Beispiel #5
0
// 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
}
Beispiel #6
0
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)
		}
	}
}
Beispiel #7
0
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
	}
}
Beispiel #8
0
// 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
}
Beispiel #9
0
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
}
Beispiel #10
0
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())
}
Beispiel #11
0
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
}
Beispiel #12
0
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
}
Beispiel #13
0
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
}