🌧 BitTorrent client and library in Go

rain

BitTorrent client and library in Go. Running in production at put.io.

Build Status GoDoc GitHub Release Go Report Card

Features

Screenshot

Rain Screenshot

Installing

If you are on MacOS you can install from brew:

brew install cenkalti/rain/rain

Otherwise, get the latest binary from releases page.

Usage as torrent client

Rain is distributed as single binary file. The main use case is running rain server command and operating the server with rain client <subcommand> commands. Server consists of a BitTorrent client and a RPC server. rain client is used to give commands to the server. There is also rain client console command which opens up a text based UI that you can view and manage the torrents on the server. Run rain help to see other commands.

Usage as library

// Create a session
ses, _ := torrent.NewSession(torrent.DefaultConfig)

// Add magnet link
tor, _ := ses.AddURI(magnetLink, nil)

// Watch the progress
for range time.Tick(time.Second) {
	s := tor.Stats()
	log.Printf("Status: %s, Downloaded: %d, Peers: %d", s.Status.String(), s.Bytes.Completed, s.Peers.Total)
}

More complete example can be found under handleDownload function at main.go file.

See package documentation for complete API.

Configuration

All values have sensible defaults, so you can run Rain with an empty config but if you want to customize it's behavior, you can pass a YAML config with -config flag. Config keys must be in lowercase. See the description of values in here: config.go

Difference from other clients

Rain is the main BitTorrent client used at put.io. It is designed to handle hundreds of torrents while using low system resources. The main difference from other clients is that Rain uses a separate peer port for each torrent. This allows Rain to download same torrent for multiple accounts in same private tracker and keep reporting their ratio correctly.

Missing features

Comments
  • How do I specify multiple files in different locations?

    How do I specify multiple files in different locations?

    Hello, trying to use the tool and I can't seem to find how to specify a list of files in different locations to be a part of the torrent. It seems I can specify a single file or a directory. However, I have files in different locations that I need to be a part of a single torrent.

  • torrent_start.go:116 cannot listen port error

    torrent_start.go:116 cannot listen port error

    2022-01-04 17:47:38 INFO     [torrent aJEicW2GEey_XQIACh5hCg] session_add.go:284 added torrent
    2022-01-04 17:47:38 INFO     [torrent aJEicW2GEey_XQIACh5hCg] torrent_start.go:31 starting torrent
    2022-01-04 17:47:38 WARNING  [torrent aJEicW2GEey_XQIACh5hCg] torrent_start.go:116 cannot listen port 53678: listen tcp4 :53678: bind: address already in use
    

    I get those errors randomly (in my tests but probably in real envs too). Since it's a warning session_add does not fail so I cannot handle the error easily. I have pre-existing code to give up / cancel a download after a certain amount of time, maybe I could use that and fail my test with a more visible error.

    Thanks for any thoughts on this. There is also something in go now to be able to double 'bind' on a port, but I don't think we want this. (so_reuse_port).

  • Saving to memory instead of disk

    Saving to memory instead of disk

    Hi there,

    How could the library be extended so that we just download the torrent but don't write it to disk, but to a memory buffer instead ?

    Would the idea be to make a 'memory-storage' out of this class/code ?

    https://github.com/cenkalti/rain/tree/master/internal/storage

    Thanks !

  • Should add timeout for udp trackers in PeriodicalAnnouncer

    Should add timeout for udp trackers in PeriodicalAnnouncer

    When the Periodical Announcer call doAnnounce with context, the context has no timeout, so it will block when a udp tracker hangs in network.

    And when udp tracker Announce hangs, it has connection lock, so then call torrent.Stop, the torrent.NotifyStop will hangs too.

    So in a session, if any udp tracker hangs in network, the stop of any torrent task will hangs for a long time (if these torrents share the same udp tracker, such as extra trackers list) , this is very bad.

    Maybe, in internal/announcer/periodic.go, the ctx should be context.WithTimeout:

    // Run the announcer goroutine. Invoke with go statement.
    
    func (a *PeriodicalAnnouncer) Run() {
    ...
    	ctx, cancel := context.WithCancel(context.Background())
    ...
    
  • Speed limit issue

    Speed limit issue

    Hello.

    I found an issue with the global download speed limit working. I have same results for tests with and without a download speed limit.

    Input data

    • golang 1.17
    • github.com/cenkalti/rain v1.8.1
    • used the same torrent file for both tests
    • ./torrent.db and data folder clean

    Test code

    func main() {
    	var limit int64
    
    	flag.Int64Var(&limit, "limit", 0, "download limit")
    	flag.Parse()
    
    	fmt.Printf("Global speed limit is %d KBps\n", limit)
    
    	cfg := torrent.DefaultConfig
    	cfg.DataDir = "./data"
    	cfg.Database = "./torrent.db"
    	cfg.SpeedLimitDownload = limit
    
    	c, _ := torrent.NewSession(cfg)
    	defer c.Close()
    
    	f, _ := os.Open("test.torrent")
    	defer f.Close()
    
    	t, _ := c.AddTorrent(f, nil)
    
    	for {
    		select {
    		case <-t.NotifyComplete():
    			fmt.Println("Done!")
    			return
    		case <-time.Tick(10 * time.Second):
    			speedKbps := t.Stats().Speed.Download / 1024
    			fmt.Printf("Speed is %d KBps\n", speedKbps)
    		}
    	}
    }
    

    Test without download limit

    # time ./test_torrent
    Global speed limit is 0 KBps
    2021-11-02 12:54:52 INFO     [session] session_load.go:34 loaded 0 existing torrents
    2021-11-02 12:54:52 INFO     [rpc server] session_rpc_server.go:48 RPC server is listening on 127.0.0.1:7246
    2021-11-02 12:54:52 INFO     [torrent 7JTQVDvCEey413Tl-RSrzA] session_add.go:284 added torrent
    2021-11-02 12:54:52 INFO     [torrent 7JTQVDvCEey413Tl-RSrzA] torrent_start.go:31 starting torrent
    2021-11-02 12:54:52 INFO     [torrent 7JTQVDvCEey413Tl-RSrzA] torrent_start.go:118 Listening peers on tcp://0.0.0.0:50898
    Speed is 6315 KBps
    Speed is 6492 KBps
    Speed is 6613 KBps
    Speed is 6629 KBps
    Speed is 6756 KBps
    Done!
    2021-11-02 12:55:43 INFO     [torrent 7JTQVDvCEey413Tl-RSrzA] torrent_write.go:82 download completed
    2021-11-02 12:55:43 INFO     [torrent 7JTQVDvCEey413Tl-RSrzA] torrent_stop.go:46 stopping torrent
    
    real    0m51,059s
    user    0m8,361s
    sys     0m11,401s
    

    Test with download limit

    # time ./test_torrent --limit=1024
    Global speed limit is 1024 KBps
    2021-11-02 12:56:24 INFO     [session] session_load.go:34 loaded 0 existing torrents
    2021-11-02 12:56:24 INFO     [rpc server] session_rpc_server.go:48 RPC server is listening on 127.0.0.1:7246
    2021-11-02 12:56:24 INFO     [torrent I2naazvDEeyA0nTl-RSrzA] session_add.go:284 added torrent
    2021-11-02 12:56:24 INFO     [torrent I2naazvDEeyA0nTl-RSrzA] torrent_start.go:31 starting torrent
    2021-11-02 12:56:24 INFO     [torrent I2naazvDEeyA0nTl-RSrzA] torrent_start.go:118 Listening peers on tcp://0.0.0.0:55204
    Speed is 6883 KBps
    Speed is 7022 KBps
    Speed is 6936 KBps
    Speed is 6922 KBps
    Speed is 6930 KBps
    Done!
    2021-11-02 12:57:15 INFO     [torrent I2naazvDEeyA0nTl-RSrzA] torrent_write.go:82 download completed
    2021-11-02 12:57:15 INFO     [torrent I2naazvDEeyA0nTl-RSrzA] torrent_stop.go:46 stopping torrent
    
    real    0m51,494s
    user    0m8,410s
    sys     0m11,407s
    
  • Health check crashes while printing a log statement

    Health check crashes while printing a log statement

    I don't know what could be done to help with those problems. Here is what the goroutine stacks looks like (edited a bit).

    goroutine 130 [select]:
    github.com/nictuku/nettools.(*ClientThrottle).cleanup(0xc000578060)
    	/var/lib/jenkins/go/pkg/mod/github.com/nictuku/[email protected]/ratelimit.go:78 +0x92
    created by github.com/nictuku/nettools.NewThrottler
    	/var/lib/jenkins/go/pkg/mod/github.com/nictuku/[email protected]/ratelimit.go:19 +0x21e
    
    goroutine 132 [select]:
    github.com/nictuku/dht.(*DHT).loop(0xc00057a000)
    	/var/lib/jenkins/go/pkg/mod/github.com/nictuku/[email protected]/dht.go:435 +0x5d2
    github.com/nictuku/dht.(*DHT).Start.func1()
    	/var/lib/jenkins/go/pkg/mod/github.com/nictuku/[email protected]/dht.go:338 +0x5d
    created by github.com/nictuku/dht.(*DHT).Start
    	/var/lib/jenkins/go/pkg/mod/github.com/nictuku/[email protected]/dht.go:336 +0x8f
    
    goroutine 146 [IO wait]:
    internal/poll.runtime_pollWait(0x7f8cd4938798, 0x72)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/runtime/netpoll.go:229 +0x89
    internal/poll.(*pollDesc).wait(0xc0001bc080, 0xc000592000, 0x0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_poll_runtime.go:84 +0x32
    internal/poll.(*pollDesc).waitRead(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_poll_runtime.go:89
    internal/poll.(*FD).ReadFrom(0xc0001bc080, {0xc000592000, 0x1000, 0x1000})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_unix.go:223 +0x238
    net.(*netFD).readFrom(0xc0001bc080, {0xc000592000, 0xffffffffffffffff, 0x0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/fd_posix.go:62 +0x29
    net.(*UDPConn).readFrom(0xc0002918e8, {0xc000592000, 0x4cd320, 0xc000353e90}, 0xc000353eb0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/udpsock_posix.go:47 +0x3e
    net.(*UDPConn).readFromUDP(0xc000388058, {0xc000592000, 0x0, 0x1}, 0x0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/udpsock.go:116 +0x31
    net.(*UDPConn).ReadFromUDP(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/udpsock.go:108
    github.com/nictuku/dht.readFromSocket(0x0, 0xc0003ea060, 0x0, 0xc000158120, {0xe2c370, 0x15323e8})
    	/var/lib/jenkins/go/pkg/mod/github.com/nictuku/[email protected]/krpc.go:235 +0xc7
    github.com/nictuku/dht.(*DHT).loop.func1()
    	/var/lib/jenkins/go/pkg/mod/github.com/nictuku/[email protected]/dht.go:406 +0x85
    created by github.com/nictuku/dht.(*DHT).loop
    	/var/lib/jenkins/go/pkg/mod/github.com/nictuku/[email protected]/dht.go:404 +0x1c7
    
    goroutine 4558 [select]:
    github.com/cenkalti/rain/internal/peerconn.(*Conn).Run(0xc00058f8b0)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:107 +0x45e
    created by github.com/cenkalti/rain/internal/peer.(*Peer).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peer/peer.go:153 +0xef
    
    goroutine 133 [chan receive]:
    github.com/rcrowley/go-metrics.(*meterArbiter).tick(0x14f8b40)
    	/var/lib/jenkins/go/pkg/mod/github.com/rcrowley/[email protected]/meter.go:239 +0x2a
    created by github.com/rcrowley/go-metrics.NewMeter
    	/var/lib/jenkins/go/pkg/mod/github.com/rcrowley/[email protected]/meter.go:46 +0xd8
    
    goroutine 134 [select]:
    github.com/cenkalti/rain/internal/resourcemanager.(*ResourceManager).run(0xc0001aa140)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/resourcemanager/resourcemanager.go:107 +0x265
    created by github.com/cenkalti/rain/internal/resourcemanager.New
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/resourcemanager/resourcemanager.go:46 +0x187
    
    goroutine 105 [select]:
    github.com/cenkalti/rain/torrent.(*Session).processDHTResults(0xc000181c00)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_dht.go:12 +0x12e
    created by github.com/cenkalti/rain/torrent.NewSession
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session.go:228 +0x1272
    
    goroutine 106 [runnable]:
    syscall.Syscall(0x4b, 0x7, 0x0, 0x0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/syscall/asm_linux_amd64.s:20 +0x5
    syscall.Fdatasync(0xc747e0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/syscall/zsyscall_linux_amd64.go:394 +0x30
    go.etcd.io/bbolt.fdatasync(0xc004565000)
    	/var/lib/jenkins/go/pkg/mod/go.etcd.io/[email protected]/bolt_linux.go:9 +0x4d
    go.etcd.io/bbolt.(*Tx).write(0xc00027e000)
    	/var/lib/jenkins/go/pkg/mod/go.etcd.io/[email protected]/tx.go:558 +0x24c
    go.etcd.io/bbolt.(*Tx).Commit(0xc00027e000)
    	/var/lib/jenkins/go/pkg/mod/go.etcd.io/[email protected]/tx.go:185 +0x1dd
    go.etcd.io/bbolt.(*DB).Update(0x1, 0xc000015ea0)
    	/var/lib/jenkins/go/pkg/mod/go.etcd.io/[email protected]/db.go:748 +0xe5
    github.com/cenkalti/rain/torrent.(*Session).updateStats(0xc000181c00)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_stats.go:119 +0xcb
    github.com/cenkalti/rain/torrent.(*Session).updateStatsLoop(0xc000181c00)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_stats.go:109 +0x85
    created by github.com/cenkalti/rain/torrent.NewSession
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session.go:230 +0x12ba
    
    goroutine 110 [IO wait]:
    internal/poll.runtime_pollWait(0x7f8cd49385c8, 0x72)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/runtime/netpoll.go:229 +0x89
    internal/poll.(*pollDesc).wait(0xc0001bc100, 0x49b786, 0x0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_poll_runtime.go:84 +0x32
    internal/poll.(*pollDesc).waitRead(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_poll_runtime.go:89
    internal/poll.(*FD).Accept(0xc0001bc100)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_unix.go:402 +0x22c
    net.(*netFD).accept(0xc0001bc100)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/fd_unix.go:173 +0x35
    net.(*TCPListener).accept(0xc00045e030)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/tcpsock_posix.go:140 +0x28
    net.(*TCPListener).Accept(0xc00045e030)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/tcpsock.go:262 +0x3d
    net/http.(*Server).Serve(0xc00027e1c0, {0xe2c790, 0xc00045e030})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/server.go:3001 +0x394
    company.com/module.foo(0x0, 0xd590cc)
    	/var/lib/jenkins/workspace/ProjectName/foo.go:564 +0x28a
    
    goroutine 112 [select]:
    net/http.(*Transport).getConn(0x149d7e0, 0xc002cb40c0, {{}, 0x0, {0xc00834a000, 0x4}, {0xc0001ce020, 0x1b}, 0x0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1372 +0x5d2
    net/http.(*Transport).roundTrip(0x149d7e0, 0xc0001be500)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:581 +0x774
    net/http.(*Transport).RoundTrip(0xc0001be500, 0xe21d40)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/roundtrip.go:18 +0x19
    net/http.send(0xc0001be300, {0xe21d40, 0x149d7e0}, {0xd2c380, 0x542501, 0x14f9140})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:252 +0x5d8
    net/http.(*Client).send(0xc000300180, 0xc0001be300, {0xc0001be300, 0x24, 0x14f9140})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:176 +0x9b
    net/http.(*Client).do(0xc000300180, 0xc0001be300)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:725 +0x908
    net/http.(*Client).Do(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:593
    net/http.(*Client).Get(0xc000496150, {0xc00834a000, 0xd5284b})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:480 +0x6a
    ...
    
    goroutine 113 [select]:
    net/http.(*Transport).getConn(0x149d7e0, 0xc00020bf00, {{}, 0x0, {0xc0079ca050, 0x4}, {0xc0009600a0, 0x1b}, 0x0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1372 +0x5d2
    net/http.(*Transport).roundTrip(0x149d7e0, 0xc003c38300)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:581 +0x774
    net/http.(*Transport).RoundTrip(0xc003c38300, 0xe21d40)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/roundtrip.go:18 +0x19
    net/http.send(0xc003c38200, {0xe21d40, 0x149d7e0}, {0xd2c380, 0x542501, 0x14f9140})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:252 +0x5d8
    net/http.(*Client).send(0xc00019c150, 0xc003c38200, {0xc003c38200, 0x2f, 0x14f9140})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:176 +0x9b
    net/http.(*Client).do(0xc00019c150, 0xc003c38200)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:725 +0x908
    net/http.(*Client).Do(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:593
    net/http.(*Client).Get(0xc0001d0070, {0xc0079ca050, 0xd5284b})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:480 +0x6a
    ...
    
    goroutine 162 [select]:
    net/http.(*Transport).getConn(0x149d7e0, 0xc00020bdc0, {{}, 0x0, {0xc00776e000, 0x4}, {0xc000960060, 0x1b}, 0x0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1372 +0x5d2
    net/http.(*Transport).roundTrip(0x149d7e0, 0xc003c38100)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:581 +0x774
    net/http.(*Transport).RoundTrip(0xc003c38100, 0xe21d40)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/roundtrip.go:18 +0x19
    net/http.send(0xc003c38000, {0xe21d40, 0x149d7e0}, {0xd2c380, 0x542501, 0x14f9140})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:252 +0x5d8
    net/http.(*Client).send(0xc0003003f0, 0xc003c38000, {0xc003c38000, 0x24, 0x14f9140})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:176 +0x9b
    net/http.(*Client).do(0xc0003003f0, 0xc003c38000)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:725 +0x908
    net/http.(*Client).Do(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:593
    net/http.(*Client).Get(0xc000496310, {0xc00776e000, 0xd5284b})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/client.go:480 +0x6a
    ...
    
    goroutine 163 [select]:
    github.com/cenkalti/rain/torrent.(*torrent).Stats(_)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_commands.go:136 +0xf5
    github.com/cenkalti/rain/torrent.(*Torrent).Stats(...)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_torrent.go:60
    company.com/module.RunDownloadTorrent(0xd53a4f, 0x1a, {0xc003f329c0, 0x5a}, 0x5)
    	...
    
    goroutine 121 [select]:
    github.com/cenkalti/rain/torrent.(*torrent).run(0xc00042db00)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_run.go:20 +0x7ca
    created by github.com/cenkalti/rain/torrent.newTorrent2
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent.go:375 +0x181a
    
    goroutine 154 [IO wait, 3 minutes]:
    internal/poll.runtime_pollWait(0x7f8cd49383f8, 0x72)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/runtime/netpoll.go:229 +0x89
    internal/poll.(*pollDesc).wait(0xc00018e180, 0xc0003a1800, 0x0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_poll_runtime.go:84 +0x32
    internal/poll.(*pollDesc).waitRead(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_poll_runtime.go:89
    internal/poll.(*FD).Read(0xc00018e180, {0xc0003a1800, 0x1784, 0x1784})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_unix.go:167 +0x25a
    net.(*netFD).Read(0xc00018e180, {0xc0003a1800, 0xc000014f08, 0x0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/fd_posix.go:56 +0x29
    net.(*conn).Read(0xc0001a2008, {0xc0003a1800, 0x2974b089, 0x15323e8})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/net.go:183 +0x45
    github.com/cenkalti/rain/internal/tracker/udptracker.(*Transport).readLoop(0xc0001aa0a0)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/tracker/udptracker/transport.go:143 +0x78
    created by github.com/cenkalti/rain/internal/tracker/udptracker.(*Transport).listen
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/tracker/udptracker/transport.go:87 +0x125
    
    goroutine 122 [select]:
    github.com/cenkalti/rain/torrent.(*Session).checkTorrent(0xc000181c00, 0xc00042db00)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_healthcheck.go:16 +0xc5
    created by github.com/cenkalti/rain/torrent.(*Session).addTorrentStopped
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_add.go:97 +0x48f
    
    goroutine 5812 [IO wait]:
    internal/poll.runtime_pollWait(0x7f8cc463e648, 0x77)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/runtime/netpoll.go:229 +0x89
    internal/poll.(*pollDesc).wait(0xc00031aa80, 0xc0005ea5a0, 0x0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_poll_runtime.go:84 +0x32
    internal/poll.(*pollDesc).waitWrite(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_poll_runtime.go:93
    internal/poll.(*FD).WaitWrite(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_unix.go:529
    net.(*netFD).connect(0xc00031aa80, {0xe31c28, 0xc000387500}, {0xc0001eb428, 0x491694}, {0xe221e0, 0xc0001ce6e0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/fd_unix.go:142 +0x717
    net.(*netFD).dial(0xc00031aa80, {0xe31c28, 0xc000387500}, {0xe37928, 0x0}, {0xe37928, 0xc0005ea510}, 0xc0001eb618)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/sock_posix.go:150 +0x379
    net.socket({0xe31c28, 0xc000387500}, {0xd41868, 0x3}, 0x2, 0x1, 0x0, 0x18, {0xe37928, 0x0}, ...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/sock_posix.go:71 +0x2a5
    net.internetSocket({0xe31c28, 0xc000387500}, {0xd41868, 0x3}, {0xe37928, 0x0}, {0xe37928, 0xc0005ea510}, 0xc001f9e080, 0x0, ...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/ipsock_posix.go:142 +0xf8
    net.(*sysDialer).doDialTCP(0xc00031aa00, {0xe31c28, 0xc000387500}, 0x0, 0xc8f4e0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/tcpsock_posix.go:66 +0xa5
    net.(*sysDialer).dialTCP(0xc000387500, {0xe31c28, 0xc000387500}, 0x294283c70d8fb009, 0x100)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/tcpsock_posix.go:62 +0x59
    net.(*sysDialer).dialSingle(0xc00031aa00, {0xe31c28, 0xc000387500}, {0xe2b318, 0xc0005ea510})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/dial.go:583 +0x28b
    net.(*sysDialer).dialSerial(0xc00031aa00, {0xe31c28, 0xc000387500}, {0xc0040ea1f0, 0x1, 0xd41cb6})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/dial.go:551 +0x312
    net.(*Dialer).DialContext(0xc000170240, {0xe31c28, 0xc000387500}, {0xd41868, 0x7f8cd40b8cf8}, {0xc000960060, 0x118})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/dial.go:428 +0x736
    net/http.(*Transport).dial(0xc000387500, {0xe31c28, 0xc000387500}, {0xd41868, 0x0}, {0xc000960060, 0x14b6260})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1166 +0xda
    net/http.(*Transport).dialConn(0x149d7e0, {0xe31c28, 0xc000387500}, {{}, 0x0, {0xc00776e000, 0x4}, {0xc000960060, 0x1b}, 0x0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1604 +0x845
    net/http.(*Transport).dialConnFor(0x8aec26, 0xc0001e42c0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1446 +0xb0
    created by net/http.(*Transport).queueForDial
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1415 +0x3d7
    
    goroutine 5716 [select]:
    github.com/cenkalti/rain/internal/peerconn/peerreader.(*PeerReader).Run(0xc003c7cd20)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerreader/peerreader.go:253 +0xe05
    created by github.com/cenkalti/rain/internal/peerconn.(*Conn).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:97 +0x1af
    
    goroutine 5704 [select]:
    github.com/cenkalti/rain/internal/peerconn/peerwriter.(*PeerWriter).messageWriter(0xc0004f6b00)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerwriter/peerwriter.go:197 +0x34f
    created by github.com/cenkalti/rain/internal/peerconn/peerwriter.(*PeerWriter).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerwriter/peerwriter.go:102 +0xb7
    
    goroutine 6133 [semacquire]:
    sync.runtime_Semacquire(0x591dee76eba21882)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/runtime/sema.go:56 +0x25
    sync.(*WaitGroup).Wait(0x15cbee640b855bf6)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/sync/waitgroup.go:130 +0x71
    github.com/prometheus/client_golang/prometheus.(*Registry).Gather.func2()
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/registry.go:463 +0x2f
    created by github.com/prometheus/client_golang/prometheus.(*Registry).Gather
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/registry.go:462 +0x56f
    
    goroutine 184 [select]:
    github.com/cenkalti/rain/torrent.(*torrent).run(0xc0004fc000)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_run.go:20 +0x7ca
    created by github.com/cenkalti/rain/torrent.newTorrent2
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent.go:375 +0x181a
    
    goroutine 143 [select]:
    github.com/cenkalti/rain/torrent.(*torrent).run(0xc0002ba480)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_run.go:20 +0x7ca
    created by github.com/cenkalti/rain/torrent.newTorrent2
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent.go:375 +0x181a
    
    goroutine 144 [select]:
    github.com/cenkalti/rain/torrent.(*Session).checkTorrent(0xc000181c00, 0xc0002ba480)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_healthcheck.go:16 +0xc5
    created by github.com/cenkalti/rain/torrent.(*Session).addTorrentStopped
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_add.go:97 +0x48f
    
    goroutine 185 [select]:
    github.com/cenkalti/rain/torrent.(*Session).checkTorrent(0xc000181c00, 0xc0004fc000)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_healthcheck.go:16 +0xc5
    created by github.com/cenkalti/rain/torrent.(*Session).addTorrentStopped
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_add.go:97 +0x48f
    
    goroutine 5642 [select]:
    github.com/cenkalti/rain/internal/announcer.(*PeriodicalAnnouncer).Run(0xc005c70000)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/announcer/periodic.go:158 +0x2dc
    created by github.com/cenkalti/rain/torrent.(*torrent).startNewAnnouncer
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_start.go:107 +0x48f
    
    goroutine 5655 [select, 3 minutes]:
    github.com/cenkalti/rain/internal/acceptor.(*Acceptor).Run.func1()
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/acceptor/acceptor.go:43 +0x65
    created by github.com/cenkalti/rain/internal/acceptor.(*Acceptor).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/acceptor/acceptor.go:42 +0x110
    
    goroutine 6123 [select]:
    net.(*netFD).connect.func2()
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/fd_unix.go:119 +0x9e
    created by net.(*netFD).connect
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/fd_unix.go:118 +0x385
    
    goroutine 2408 [select]:
    github.com/cenkalti/rain/torrent.(*Session).checkTorrent(0xc000181c00, 0xc000666900)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_healthcheck.go:16 +0xc5
    created by github.com/cenkalti/rain/torrent.(*Session).addTorrentStopped
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_add.go:97 +0x48f
    
    goroutine 5980 [select]:
    github.com/cenkalti/rain/internal/peer.(*Peer).Run(0xc000522a00, 0xc003f33980, 0xc003f339e0, 0xc003f33a40, 0xc003f33920)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peer/peer.go:167 +0x467
    created by github.com/cenkalti/rain/torrent.(*torrent).startPeer
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_peer.go:149 +0x4af
    
    goroutine 5701 [select]:
    github.com/cenkalti/rain/internal/peerconn.(*Conn).Run(0xc007d33090)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:107 +0x45e
    created by github.com/cenkalti/rain/internal/peer.(*Peer).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peer/peer.go:153 +0xef
    
    goroutine 2260 [select]:
    github.com/cenkalti/rain/torrent.(*Session).checkTorrent(0xc000181c00, 0xc000666000)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_healthcheck.go:16 +0xc5
    created by github.com/cenkalti/rain/torrent.(*Session).addTorrentStopped
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_add.go:97 +0x48f
    
    goroutine 5703 [select, 1 minutes]:
    github.com/cenkalti/rain/internal/peerconn/peerwriter.(*PeerWriter).Run(0xc0004f6b00)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerwriter/peerwriter.go:115 +0x1f9
    created by github.com/cenkalti/rain/internal/peerconn.(*Conn).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:100 +0x23b
    
    goroutine 5969 [runnable]:
    net._C2func_getaddrinfo(0xc0005560a0, 0x0, 0xc003caa0f0, 0xc0005a0040)
    	_cgo_gotypes.go:91 +0x56
    net.cgoLookupIPCNAME.func1({0xc0005560a0, 0xc0002f7d10, 0x79e2ed}, 0xc003e48d56, 0xc000781440)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/cgo_unix.go:163 +0x9f
    net.cgoLookupIPCNAME({0xd41477, 0x2}, {0xc003e48d56, 0xc000758768})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/cgo_unix.go:163 +0x16d
    net.cgoIPLookup(0x57d6f0, {0xd41477, 0xe3d601}, {0xc003e48d56, 0x15320a0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/cgo_unix.go:220 +0x3b
    created by net.cgoLookupIP
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/cgo_unix.go:230 +0x125
    
    goroutine 5750 [select]:
    github.com/cenkalti/rain/internal/peer.(*Peer).Run(0xc002531500, 0xc003f33980, 0xc003f339e0, 0xc003f33a40, 0xc003f33920)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peer/peer.go:176 +0x32f
    created by github.com/cenkalti/rain/torrent.(*torrent).startPeer
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_peer.go:149 +0x4af
    
    goroutine 5715 [select]:
    github.com/cenkalti/rain/internal/peerconn.(*Conn).Run(0xc00058f950)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:107 +0x45e
    created by github.com/cenkalti/rain/internal/peer.(*Peer).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peer/peer.go:153 +0xef
    
    goroutine 5652 [runnable]:
    runtime.CallersFrames(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/runtime/symtab.go:66
    runtime.Caller(0x2)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/runtime/extern.go:203 +0x7e
    github.com/cenkalti/log.(*logger).log(0xc0003017a0, 0x5, {0xc0004fa030, 0x2d})
    	/var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/logger.go:89 +0x4e
    github.com/cenkalti/log.(*logger).Debugf(0xc0002ec000, {0xd5a63d, 0xc002531300}, {0xc007940000, 0xc005196000, 0x400000})
    	/var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/logger.go:209 +0x4c
    github.com/cenkalti/rain/torrent.(*torrent).startSinglePieceDownloader(0xc003f0c900, 0xc002531300)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_start.go:228 +0x31f
    github.com/cenkalti/rain/torrent.(*torrent).startPieceDownloaderFor(0xc003f0c900, 0xc002531300)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_start.go:206 +0xe7
    github.com/cenkalti/rain/torrent.(*torrent).handlePieceMessage(0xc003f0c900, {0xc002531300, {{0x299, 0x3fc000}, {{0xc001c2a000, 0x4000, 0x4000}, 0xc007d7e270, 0xc00019c570}}})
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_messagehandler.go:104 +0x9e5
    github.com/cenkalti/rain/torrent.(*torrent).run(0xc003f0c900)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_run.go:86 +0xf85
    created by github.com/cenkalti/rain/torrent.newTorrent2
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent.go:375 +0x181a
    
    goroutine 4557 [select]:
    github.com/cenkalti/rain/internal/peer.(*Peer).Run(0xc002531300, 0xc003f33980, 0xc003f339e0, 0xc003f33a40, 0xc003f33920)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peer/peer.go:176 +0x32f
    created by github.com/cenkalti/rain/torrent.(*torrent).startPeer
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_peer.go:149 +0x4af
    
    goroutine 2426 [select]:
    github.com/cenkalti/rain/torrent.(*torrent).run(0xc0004fcd80)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_run.go:20 +0x7ca
    created by github.com/cenkalti/rain/torrent.newTorrent2
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent.go:375 +0x181a
    
    goroutine 2259 [select]:
    github.com/cenkalti/rain/torrent.(*torrent).run(0xc000666000)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_run.go:20 +0x7ca
    created by github.com/cenkalti/rain/torrent.newTorrent2
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent.go:375 +0x181a
    
    goroutine 5700 [select]:
    github.com/cenkalti/rain/internal/peer.(*Peer).Run(0xc002a25300, 0xc003f33980, 0xc003f339e0, 0xc003f33a40, 0xc003f33920)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peer/peer.go:167 +0x467
    created by github.com/cenkalti/rain/torrent.(*torrent).startPeer
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_peer.go:149 +0x4af
    
    goroutine 4586 [select]:
    github.com/nictuku/dht.pingSlowly(0xc00075b7d0, {0xc00074a000, 0x306, 0xc003f33aa0}, 0xc003d52600, 0xc000158120)
    	/var/lib/jenkins/go/pkg/mod/github.com/nictuku/[email protected]/routing_table.go:292 +0x114
    github.com/nictuku/dht.(*DHT).loop.func2()
    	/var/lib/jenkins/go/pkg/mod/github.com/nictuku/[email protected]/dht.go:510 +0x85
    created by github.com/nictuku/dht.(*DHT).loop
    	/var/lib/jenkins/go/pkg/mod/github.com/nictuku/[email protected]/dht.go:508 +0xb05
    
    goroutine 5753 [select, 1 minutes]:
    github.com/cenkalti/rain/internal/peerconn/peerwriter.(*PeerWriter).Run(0xc0001bd200)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerwriter/peerwriter.go:115 +0x1f9
    created by github.com/cenkalti/rain/internal/peerconn.(*Conn).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:100 +0x23b
    
    goroutine 1195 [select]:
    github.com/cenkalti/rain/torrent.(*Session).checkTorrent(0xc000181c00, 0xc000666480)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_healthcheck.go:16 +0xc5
    created by github.com/cenkalti/rain/torrent.(*Session).addTorrentStopped
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_add.go:97 +0x48f
    
    goroutine 5643 [runnable]:
    syscall.Syscall(0x3, 0x10, 0x0, 0x0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/syscall/asm_linux_amd64.s:20 +0x5
    syscall.Close(0x7f8cd4938228)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/syscall/zsyscall_linux_amd64.go:286 +0x30
    internal/poll.(*FD).destroy(0xc0004f6880)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_unix.go:84 +0x51
    internal/poll.(*FD).readUnlock(0xc0004f6880)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_mutex.go:232 +0x33
    internal/poll.(*FD).Read(0xc0004f6880, {0xc0119f4000, 0x400000, 0x400000})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_unix.go:173 +0x31e
    net.(*netFD).Read(0xc0004f6880, {0xc0119f4000, 0x82572d, 0x824b85})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/fd_posix.go:56 +0x29
    net.(*conn).Read(0xc00063a1a0, {0xc0119f4000, 0x0, 0x0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/net.go:183 +0x45
    net/http.(*persistConn).Read(0xc005c70120, {0xc0119f4000, 0x0, 0x0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1926 +0x4e
    bufio.(*Reader).Read(0xc0005dbf20, {0xc0119f4000, 0x400000, 0x400000})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/bufio/bufio.go:213 +0x106
    io.(*LimitedReader).Read(0xc007d7e0a8, {0xc0119f4000, 0x491705, 0x1000000004e5e7a})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/io/io.go:473 +0x45
    net/http.(*body).readLocked(0xc0013c68c0, {0xc0119f4000, 0x400000, 0xc000306000})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transfer.go:843 +0x3c
    net/http.(*body).Read(0x8, {0xc0119f4000, 0x400000, 0xc0079da4f8})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transfer.go:835 +0x125
    net/http.(*bodyEOFSignal).Read(0xc0013c6900, {0xc0119f4000, 0x400000, 0x400000})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:2768 +0x142
    github.com/cenkalti/rain/internal/urldownloader.readFull({0xe21d60, 0xc0013c6900}, {0xc0119f4000, 0x400000, 0x400000}, 0x52, 0x0)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/urldownloader/urldownloader.go:159 +0x79
    github.com/cenkalti/rain/internal/urldownloader.(*URLDownloader).Run.func2({{0xc003e48990, 0x400000}, 0x4ea64e, 0x29b00000000})
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/urldownloader/urldownloader.go:115 +0x945
    github.com/cenkalti/rain/internal/urldownloader.(*URLDownloader).Run(0xc0007f8450, 0xc000181ed0, {0xc001476000, 0x29b, 0x29b}, 0x0, 0xc003d52540, 0xc000301a70, 0x2540be400)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/urldownloader/urldownloader.go:138 +0x385
    created by github.com/cenkalti/rain/torrent.(*torrent).startWebseedDownloader
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_start.go:193 +0x45f
    
    goroutine 5968 [select]:
    net.cgoLookupIP({0xe31bb8, 0xc00838e040}, {0xd41477, 0x18}, {0xc003e48d56, 0xc000593000})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/cgo_unix.go:231 +0x1b7
    net.(*Resolver).lookupIP(0x14f7e40, {0xe31bb8, 0xc00838e040}, {0xd41477, 0x2}, {0xc003e48d56, 0x18})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/lookup_unix.go:97 +0x128
    net.glob..func1({0xe31bb8, 0xc00838e040}, 0x68, {0xd41477, 0x70}, {0xc003e48d56, 0x400000})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/hook.go:23 +0x3d
    net.(*Resolver).lookupIPAddr.func1()
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/lookup.go:296 +0x9f
    internal/singleflight.(*Group).doCall(0x14f7e50, 0xc008e84690, {0xc000556040, 0x1b}, 0xc000276810)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/singleflight/singleflight.go:95 +0x3b
    created by internal/singleflight.(*Group).DoChan
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/singleflight/singleflight.go:88 +0x2f1
    
    goroutine 5983 [select, 1 minutes]:
    github.com/cenkalti/rain/internal/peerconn/peerwriter.(*PeerWriter).Run(0xc0001bc300)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerwriter/peerwriter.go:115 +0x1f9
    created by github.com/cenkalti/rain/internal/peerconn.(*Conn).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:100 +0x23b
    
    goroutine 5717 [select, 1 minutes]:
    github.com/cenkalti/rain/internal/peerconn/peerwriter.(*PeerWriter).Run(0xc0001bd000)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerwriter/peerwriter.go:115 +0x1f9
    created by github.com/cenkalti/rain/internal/peerconn.(*Conn).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:100 +0x23b
    
    goroutine 5702 [select]:
    github.com/cenkalti/rain/internal/peerconn/peerreader.(*PeerReader).Run(0xc0003145a0)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerreader/peerreader.go:253 +0xe05
    created by github.com/cenkalti/rain/internal/peerconn.(*Conn).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:97 +0x1af
    
    goroutine 4560 [select, 1 minutes]:
    github.com/cenkalti/rain/internal/peerconn/peerwriter.(*PeerWriter).Run(0xc0001bcf00)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerwriter/peerwriter.go:115 +0x1f9
    created by github.com/cenkalti/rain/internal/peerconn.(*Conn).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:100 +0x23b
    
    goroutine 5718 [select]:
    github.com/cenkalti/rain/internal/peerconn/peerwriter.(*PeerWriter).messageWriter(0xc0001bd000)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerwriter/peerwriter.go:197 +0x34f
    created by github.com/cenkalti/rain/internal/peerconn/peerwriter.(*PeerWriter).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerwriter/peerwriter.go:102 +0xb7
    
    goroutine 2794 [select]:
    github.com/cenkalti/rain/internal/peer.(*Peer).Run(0xc000522300, 0xc003f33980, 0xc003f339e0, 0xc003f33a40, 0xc003f33920)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peer/peer.go:176 +0x32f
    created by github.com/cenkalti/rain/torrent.(*torrent).startPeer
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_peer.go:149 +0x4af
    
    goroutine 5714 [select]:
    github.com/cenkalti/rain/internal/peer.(*Peer).Run(0xc002531400, 0xc003f33980, 0xc003f339e0, 0xc003f33a40, 0xc003f33920)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peer/peer.go:176 +0x32f
    created by github.com/cenkalti/rain/torrent.(*torrent).startPeer
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_peer.go:149 +0x4af
    
    goroutine 2796 [select]:
    github.com/cenkalti/rain/internal/peerconn/peerreader.(*PeerReader).Run(0xc00141b620)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerreader/peerreader.go:253 +0xe05
    created by github.com/cenkalti/rain/internal/peerconn.(*Conn).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:97 +0x1af
    
    goroutine 4784 [select]:
    github.com/cenkalti/rain/torrent.(*torrent).run(0xc005ad7680)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_run.go:20 +0x7ca
    created by github.com/cenkalti/rain/torrent.newTorrent2
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent.go:375 +0x181a
    
    goroutine 1194 [select]:
    github.com/cenkalti/rain/torrent.(*torrent).run(0xc000666480)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_run.go:20 +0x7ca
    created by github.com/cenkalti/rain/torrent.newTorrent2
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent.go:375 +0x181a
    
    goroutine 2427 [select]:
    github.com/cenkalti/rain/torrent.(*Session).checkTorrent(0xc000181c00, 0xc0004fcd80)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_healthcheck.go:16 +0xc5
    created by github.com/cenkalti/rain/torrent.(*Session).addTorrentStopped
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_add.go:97 +0x48f
    
    goroutine 4785 [select]:
    github.com/cenkalti/rain/torrent.(*Session).checkTorrent(0xc000181c00, 0xc005ad7680)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_healthcheck.go:16 +0xc5
    created by github.com/cenkalti/rain/torrent.(*Session).addTorrentStopped
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/session_add.go:97 +0x48f
    
    goroutine 2795 [select]:
    github.com/cenkalti/rain/internal/peerconn.(*Conn).Run(0xc007a9ed20)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:107 +0x45e
    created by github.com/cenkalti/rain/internal/peer.(*Peer).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peer/peer.go:153 +0xef
    
    goroutine 6132 [runnable]:
    syscall.Syscall(0x0, 0x1a, 0xc0001da400, 0x200)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/syscall/asm_linux_amd64.s:20 +0x5
    syscall.read(0xc003f6c0c0, {0xc0001da400, 0x320200000001, 0xc00073e820})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/syscall/zsyscall_linux_amd64.go:687 +0x4d
    syscall.Read(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/syscall/syscall_unix.go:189
    internal/poll.ignoringEINTRIO(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_unix.go:582
    internal/poll.(*FD).Read(0xc003f6c0c0, {0xc0001da400, 0x200, 0x200})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_unix.go:163 +0x285
    os.(*File).read(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/os/file_posix.go:32
    os.(*File).Read(0xc000388068, {0xc0001da400, 0xc60880, 0xc00046af01})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/os/file.go:119 +0x5e
    io.(*LimitedReader).Read(0xc003dd65d0, {0xc0001da400, 0x18, 0x7f8cfd5cfa68})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/io/io.go:473 +0x45
    io.ReadAll({0xe21a80, 0xc003dd65d0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/io/io.go:633 +0xfe
    io/ioutil.ReadAll(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/io/ioutil/ioutil.go:27
    github.com/prometheus/procfs/internal/util.ReadFileNoStat({0xc0005e60f0, 0xc000144070})
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/internal/util/readfile.go:37 +0xd4
    github.com/prometheus/procfs.FS.Stat({{_, _}})
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/stat.go:169 +0x126
    github.com/prometheus/procfs.ProcStat.StartTime({0x9704, {0xc0005e6050, 0xc}, {0x14c11d0, 0x1}, 0x1, 0x9704, 0x9704, 0x0, 0xffffffffffffffff, ...})
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/proc_stat.go:179 +0x78
    github.com/prometheus/client_golang/prometheus.(*processCollector).processCollect(0xc0001aa9b0, 0xc000352f20)
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/process_collector_other.go:44 +0x725
    github.com/prometheus/client_golang/prometheus.(*processCollector).Collect(0xc000352fb0, 0xc000352f60)
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/process_collector.go:138 +0x1f
    github.com/prometheus/client_golang/prometheus.(*Registry).Gather.func1()
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/registry.go:446 +0x102
    created by github.com/prometheus/client_golang/prometheus.(*Registry).Gather
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/registry.go:457 +0x4e8
    
    goroutine 2407 [select]:
    github.com/cenkalti/rain/torrent.(*torrent).run(0xc000666900)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_run.go:20 +0x7ca
    created by github.com/cenkalti/rain/torrent.newTorrent2
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent.go:375 +0x181a
    
    goroutine 6122 [select]:
    net.(*netFD).connect.func2()
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/fd_unix.go:119 +0x9e
    created by net.(*netFD).connect
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/fd_unix.go:118 +0x385
    
    goroutine 6124 [select]:
    net.(*netFD).connect.func2()
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/fd_unix.go:119 +0x9e
    created by net.(*netFD).connect
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/fd_unix.go:118 +0x385
    
    goroutine 5752 [select]:
    github.com/cenkalti/rain/internal/peerconn/peerreader.(*PeerReader).Run(0xc003c7da40)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerreader/peerreader.go:253 +0xe05
    created by github.com/cenkalti/rain/internal/peerconn.(*Conn).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:97 +0x1af
    
    goroutine 5813 [runnable]:
    internal/poll.runtime_pollWait(0x7f8cd4937a00, 0x77)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/runtime/netpoll.go:229 +0x89
    internal/poll.(*pollDesc).wait(0xc00031a800, 0xc0005ea420, 0x0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_poll_runtime.go:84 +0x32
    internal/poll.(*pollDesc).waitWrite(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_poll_runtime.go:93
    internal/poll.(*FD).WaitWrite(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_unix.go:529
    net.(*netFD).connect(0xc00031a800, {0xe31c28, 0xc000387aa0}, {0xc0001ed428, 0x491694}, {0xe221e0, 0xc0001ce240})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/fd_unix.go:142 +0x717
    net.(*netFD).dial(0xc00031a800, {0xe31c28, 0xc000387aa0}, {0xe37928, 0x0}, {0xe37928, 0xc0005ea3f0}, 0xc0001ed618)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/sock_posix.go:150 +0x379
    net.socket({0xe31c28, 0xc000387aa0}, {0xd41868, 0x3}, 0x2, 0x1, 0x0, 0x18, {0xe37928, 0x0}, ...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/sock_posix.go:71 +0x2a5
    net.internetSocket({0xe31c28, 0xc000387aa0}, {0xd41868, 0x3}, {0xe37928, 0x0}, {0xe37928, 0xc0005ea3f0}, 0xc001f9e080, 0x0, ...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/ipsock_posix.go:142 +0xf8
    net.(*sysDialer).doDialTCP(0xc00031a280, {0xe31c28, 0xc000387aa0}, 0x0, 0xc8f4e0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/tcpsock_posix.go:66 +0xa5
    net.(*sysDialer).dialTCP(0xc000387aa0, {0xe31c28, 0xc000387aa0}, 0x49b786, 0x2000)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/tcpsock_posix.go:62 +0x59
    net.(*sysDialer).dialSingle(0xc00031a280, {0xe31c28, 0xc000387aa0}, {0xe2b318, 0xc0005ea3f0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/dial.go:583 +0x28b
    net.(*sysDialer).dialSerial(0xc00031a280, {0xe31c28, 0xc000387aa0}, {0xc0040ea1b0, 0x1, 0xd41cb6})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/dial.go:551 +0x312
    net.(*Dialer).DialContext(0xc000170240, {0xe31c28, 0xc000387aa0}, {0xd41868, 0x7f8cd40b8cf8}, {0xc0009600a0, 0x118})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/dial.go:428 +0x736
    net/http.(*Transport).dial(0xc000387aa0, {0xe31c28, 0xc000387aa0}, {0xd41868, 0x0}, {0xc0009600a0, 0x14b6260})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1166 +0xda
    net/http.(*Transport).dialConn(0x149d7e0, {0xe31c28, 0xc000387aa0}, {{}, 0x0, {0xc0079ca050, 0x4}, {0xc0009600a0, 0x1b}, 0x0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1604 +0x845
    net/http.(*Transport).dialConnFor(0xe21620, 0xc0001e4370)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1446 +0xb0
    created by net/http.(*Transport).queueForDial
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1415 +0x3d7
    
    goroutine 5751 [select]:
    github.com/cenkalti/rain/internal/peerconn.(*Conn).Run(0xc0075efc20)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:107 +0x45e
    created by github.com/cenkalti/rain/internal/peer.(*Peer).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peer/peer.go:153 +0xef
    
    goroutine 2797 [select, 1 minutes]:
    github.com/cenkalti/rain/internal/peerconn/peerwriter.(*PeerWriter).Run(0xc0002f4380)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerwriter/peerwriter.go:115 +0x1f9
    created by github.com/cenkalti/rain/internal/peerconn.(*Conn).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:100 +0x23b
    
    goroutine 5649 [semacquire]:
    internal/poll.runtime_Semacquire(0x7f8cd4938228)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/runtime/sema.go:61 +0x25
    internal/poll.(*FD).Close(0xc0004f6880)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_unix.go:116 +0x6d
    net.(*netFD).Close(0xc0004f6880)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/fd_posix.go:38 +0x38
    net.(*conn).Close(0xc00063a1a0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/net.go:207 +0x45
    net/http.(*persistConn).closeLocked(0xc005c70120, {0xe21620, 0xc0000209d0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:2708 +0x130
    net/http.(*persistConn).cancelRequest(0xc000709d40, {0xe21620, 0xc000020280})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1974 +0xe5
    net/http.(*Transport).cancelRequest(0xc00021a280, {0xc00055eda8}, {0xe21620, 0xc000020280})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:798 +0xee
    net/http.(*persistConn).readLoop(0xc005c70120)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:2223 +0xdf7
    created by net/http.(*Transport).dialConn
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1747 +0x1e05
    
    goroutine 5644 [select, 3 minutes]:
    github.com/cenkalti/rain/internal/urldownloader.(*URLDownloader).Run.func1()
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/urldownloader/urldownloader.go:78 +0x65
    created by github.com/cenkalti/rain/internal/urldownloader.(*URLDownloader).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/urldownloader/urldownloader.go:77 +0x13d
    
    goroutine 5641 [select]:
    github.com/cenkalti/rain/internal/acceptor.(*Acceptor).Run(0xc000f241c0)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/acceptor/acceptor.go:60 +0x1c7
    created by github.com/cenkalti/rain/torrent.(*torrent).startAcceptor
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/torrent/torrent_start.go:122 +0x3c8
    
    goroutine 5981 [select]:
    github.com/cenkalti/rain/internal/peerconn.(*Conn).Run(0xc0002f7d10)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:107 +0x45e
    created by github.com/cenkalti/rain/internal/peer.(*Peer).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peer/peer.go:153 +0xef
    
    goroutine 6134 [runnable]:
    syscall.Syscall(0x0, 0x19, 0xc002cb6000, 0x200)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/syscall/asm_linux_amd64.s:20 +0x5
    syscall.read(0xc00057c060, {0xc002cb6000, 0x490e01, 0x7f8cc46f1878})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/syscall/zsyscall_linux_amd64.go:687 +0x4d
    syscall.Read(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/syscall/syscall_unix.go:189
    internal/poll.ignoringEINTRIO(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_unix.go:582
    internal/poll.(*FD).Read(0xc00057c060, {0xc002cb6000, 0x200, 0x200})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_unix.go:163 +0x285
    os.(*File).read(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/os/file_posix.go:32
    os.(*File).Read(0xc00063a008, {0xc002cb6000, 0xc60880, 0xc000792f01})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/os/file.go:119 +0x5e
    io.(*LimitedReader).Read(0xc000602000, {0xc002cb6000, 0x18, 0x7f8cfd5d03c8})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/io/io.go:473 +0x45
    io.ReadAll({0xe21a80, 0xc000602000})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/io/io.go:633 +0xfe
    io/ioutil.ReadAll(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/io/ioutil/ioutil.go:27
    github.com/prometheus/procfs/internal/util.ReadFileNoStat({0xc003db4060, 0xc0001a4010})
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/internal/util/readfile.go:37 +0xd4
    github.com/prometheus/procfs.FS.Stat({{_, _}})
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/stat.go:169 +0x126
    github.com/prometheus/procfs.ProcStat.StartTime({0x9704, {0xc002140140, 0xc}, {0x14c11d8, 0x1}, 0x1, 0x9704, 0x9704, 0x0, 0xffffffffffffffff, ...})
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/proc_stat.go:179 +0x78
    github.com/prometheus/client_golang/prometheus.(*processCollector).processCollect(0xc0001567d0, 0xc000171e00)
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/process_collector_other.go:44 +0x725
    github.com/prometheus/client_golang/prometheus.(*processCollector).Collect(0xc00047afb0, 0xc00047af60)
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/process_collector.go:138 +0x1f
    github.com/prometheus/client_golang/prometheus.(*Registry).Gather.func1()
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/registry.go:446 +0x102
    created by github.com/prometheus/client_golang/prometheus.(*Registry).Gather
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/registry.go:538 +0xb4d
    
    goroutine 5666 [select, 3 minutes]:
    net/http.(*persistConn).writeLoop(0xc005c70120)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:2386 +0xfb
    created by net/http.(*Transport).dialConn
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1748 +0x1e65
    
    goroutine 6119 [runnable]:
    internal/poll.runtime_pollWait(0x7f8cd4938140, 0x77)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/runtime/netpoll.go:229 +0x89
    internal/poll.(*pollDesc).wait(0xc00031a980, 0xc0005ea4b0, 0x0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_poll_runtime.go:84 +0x32
    internal/poll.(*pollDesc).waitWrite(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_poll_runtime.go:93
    internal/poll.(*FD).WaitWrite(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/internal/poll/fd_unix.go:529
    net.(*netFD).connect(0xc00031a980, {0xe31c28, 0xc007aeaba0}, {0xc0007eb428, 0x491694}, {0xe221e0, 0xc0001ce6c0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/fd_unix.go:142 +0x717
    net.(*netFD).dial(0xc00031a980, {0xe31c28, 0xc007aeaba0}, {0xe37928, 0x0}, {0xe37928, 0xc0005ea480}, 0xc0007eb618)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/sock_posix.go:150 +0x379
    net.socket({0xe31c28, 0xc007aeaba0}, {0xd41868, 0x3}, 0x2, 0x1, 0x0, 0x18, {0xe37928, 0x0}, ...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/sock_posix.go:71 +0x2a5
    net.internetSocket({0xe31c28, 0xc007aeaba0}, {0xd41868, 0x3}, {0xe37928, 0x0}, {0xe37928, 0xc0005ea480}, 0xc001f9e080, 0x0, ...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/ipsock_posix.go:142 +0xf8
    net.(*sysDialer).doDialTCP(0xc00031a900, {0xe31c28, 0xc007aeaba0}, 0x0, 0xc8f4e0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/tcpsock_posix.go:66 +0xa5
    net.(*sysDialer).dialTCP(0xc007aeaba0, {0xe31c28, 0xc007aeaba0}, 0xefbc4b2c1df0c233, 0xccbfe824f0b815df)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/tcpsock_posix.go:62 +0x59
    net.(*sysDialer).dialSingle(0xc00031a900, {0xe31c28, 0xc007aeaba0}, {0xe2b318, 0xc0005ea480})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/dial.go:583 +0x28b
    net.(*sysDialer).dialSerial(0xc00031a900, {0xe31c28, 0xc007aeaba0}, {0xc0040ea1d0, 0x1, 0xd41cb6})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/dial.go:551 +0x312
    net.(*Dialer).DialContext(0xc000170240, {0xe31c28, 0xc007aeaba0}, {0xd41868, 0x7f8cd40b65a8}, {0xc0001ce020, 0x118})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/dial.go:428 +0x736
    net/http.(*Transport).dial(0xc007aeaba0, {0xe31c28, 0xc007aeaba0}, {0xd41868, 0x811cc3d00d01cfa7}, {0xc0001ce020, 0x3189c3ce469a236d})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1166 +0xda
    net/http.(*Transport).dialConn(0x149d7e0, {0xe31c28, 0xc007aeaba0}, {{}, 0x0, {0xc00834a000, 0x4}, {0xc0001ce020, 0x1b}, 0x0})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1604 +0x845
    net/http.(*Transport).dialConnFor(0xc003f33a40, 0xc003ef8000)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1446 +0xb0
    created by net/http.(*Transport).queueForDial
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/transport.go:1415 +0x3d7
    
    goroutine 4559 [select]:
    github.com/cenkalti/rain/internal/peerconn/peerreader.(*PeerReader).Run(0xc003c7cae0)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerreader/peerreader.go:253 +0xe05
    created by github.com/cenkalti/rain/internal/peerconn.(*Conn).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:97 +0x1af
    
    goroutine 5984 [select]:
    github.com/cenkalti/rain/internal/peerconn/peerwriter.(*PeerWriter).messageWriter(0xc0001bc300)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerwriter/peerwriter.go:197 +0x34f
    created by github.com/cenkalti/rain/internal/peerconn/peerwriter.(*PeerWriter).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerwriter/peerwriter.go:102 +0xb7
    
    goroutine 5982 [select]:
    github.com/cenkalti/rain/internal/peerconn/peerreader.(*PeerReader).Run(0xc007aea1e0)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerreader/peerreader.go:253 +0xe05
    created by github.com/cenkalti/rain/internal/peerconn.(*Conn).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerconn.go:97 +0x1af
    
    goroutine 5967 [select]:
    net.(*Resolver).lookupIPAddr(0x14f7e40, {0xe31c28, 0xc003c180c0}, {0xd41477, 0x49b00f}, {0xc003e48d56, 0x18})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/lookup.go:302 +0x5c7
    net.(*Resolver).LookupIPAddr(...)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/lookup.go:207
    github.com/cenkalti/rain/internal/resolver.ResolveIPv4({0xe31bb8, 0xc000518700}, 0x491694, {0xc003e48d56, 0x18})
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/resolver/resolver.go:57 +0xb2
    github.com/cenkalti/rain/internal/resolver.Resolve({0xe31bb8, 0xc000518700}, {0xc003e48d56, 0xc0020edc38}, 0x4919e7, 0xc000192300)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/resolver/resolver.go:37 +0xb2
    github.com/cenkalti/rain/internal/tracker/udptracker.(*Transport).Do(0xc0001aa0a0, {0xe31bb8, 0xc000518700}, 0xc003c18000)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/tracker/udptracker/transport.go:97 +0x7a
    github.com/cenkalti/rain/internal/tracker/udptracker.(*UDPTracker).Announce(0xc0003d6d20, {0xe31bb8, 0xc000518700}, {{0x2744000, 0x4f906d38, 0x58000000, {0xb1, 0xd2, 0x5b, 0x6d, ...}, ...}, ...})
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/tracker/udptracker/udptracker.go:67 +0x153
    github.com/cenkalti/rain/internal/tracker.(*Tier).Announce(0xc0077f4560, {0xe31bb8, 0xc000518700}, {{0x2744000, 0x4f906d38, 0x58000000, {0xb1, 0xd2, 0x5b, 0x6d, ...}, ...}, ...})
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/tracker/tier.go:32 +0x95
    github.com/cenkalti/rain/internal/announcer.announce({0xe31bb8, 0xc000518700}, {0xe2ac10, 0xc0077f4560}, 0x147a2c0, 0xc00abf2000, {0x2744000, 0x4f906d38, 0x58000000, {0xb1, ...}, ...}, ...)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/announcer/announce.go:24 +0x143
    github.com/cenkalti/rain/internal/announcer.(*PeriodicalAnnouncer).announce(0xc005c70000, {0xe31bb8, 0xc000518700}, 0x192600, 0xc000276810)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/announcer/periodic.go:244 +0x11e
    created by github.com/cenkalti/rain/internal/announcer.(*PeriodicalAnnouncer).doAnnounce
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/announcer/periodic.go:238 +0xb7
    
    goroutine 2798 [select]:
    github.com/cenkalti/rain/internal/peerconn/peerwriter.(*PeerWriter).messageWriter(0xc0002f4380)
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerwriter/peerwriter.go:197 +0x34f
    created by github.com/cenkalti/rain/internal/peerconn/peerwriter.(*PeerWriter).Run
    	/var/lib/jenkins/go/pkg/mod/github.com/bsergean/[email protected]/internal/peerconn/peerwriter/peerwriter.go:102 +0xb7
    
    goroutine 5916 [select]:
    github.com/prometheus/client_golang/prometheus.(*Registry).Gather(0xc0001aa960)
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/registry.go:513 +0x945
    github.com/prometheus/client_golang/prometheus/promhttp.HandlerFor.func1({0x7f8cc419a278, 0xc003f73c70}, 0xc000392100)
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/promhttp/http.go:126 +0x108
    net/http.HandlerFunc.ServeHTTP(0xe22880, {0x7f8cc419a278, 0xc003f73c70}, 0xc0012de210)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/server.go:2046 +0x2f
    github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerInFlight.func1({0x7f8cc419a278, 0xc003f73c70}, 0xc003f73c70)
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/promhttp/instrument_server.go:40 +0xd4
    net/http.HandlerFunc.ServeHTTP(0xe2c9a0, {0x7f8cc419a278, 0xc003f73c70}, 0x716085)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/server.go:2046 +0x2f
    github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerCounter.func1({0xe2c9a0, 0xc0006780e0}, 0xc000392100)
    	/var/lib/jenkins/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/promhttp/instrument_server.go:101 +0x92
    net/http.HandlerFunc.ServeHTTP(0x0, {0xe2c9a0, 0xc0006780e0}, 0x0)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/server.go:2046 +0x2f
    net/http.(*ServeMux).ServeHTTP(0x0, {0xe2c9a0, 0xc0006780e0}, 0xc000392100)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/server.go:2424 +0x149
    net/http.serverHandler.ServeHTTP({0xc00078bda0}, {0xe2c9a0, 0xc0006780e0}, 0xc000392100)
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/server.go:2878 +0x43b
    net/http.(*conn).serve(0xc0011cc140, {0xe31c60, 0xc00019c690})
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/server.go:1929 +0xb08
    created by net/http.(*Server).Serve
    	/var/lib/jenkins/workspace/ProjectName/golang/go/src/net/http/server.go:3033 +0x4e8
    
  • Status: Stopped: file allocation error

    Status: Stopped: file allocation error

    previously, i nothing issue using rain as torrent client, currently i have an issue when i download a file with size 104597 MiB , i'm not sure this issue about size

    here general info about my torrent

    Name: Mytorrent-test
    Private: false
    Status: Stopped: file allocation error: open /root/rain/data/CsifRcHWEeyOJwLUlt2y4A/Mytorrent-test/media/Stripped/MediaOverride/x10/test/CHARACTER_Driver.zip: too many open files
    Progress: 0%
    Ratio: 0.00
    Size: 104597 MiB
    Peers: 0 in / 0 out
    Download speed:     0 KiB/s
    Upload speed:       0 KiB/s
    ETA:
    
  • Patch #35

    Patch #35

    See https://github.com/cenkalti/rain/issues/35

    I am not super sure if we need both mutex, because it is probably the same torrents that are stuffed in the 2 maps.

  • Data race in Tier.go Announce method

    Data race in Tier.go Announce method

    I have 2 sessions objects, and I run a download for both.

    Here is the race report.

    ==================
    WARNING: DATA RACE
    Read at 0x00c000666678 by goroutine 81:
      github.com/cenkalti/rain/internal/tracker.(*Tier).Announce()
          /var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/internal/tracker/tier.go:27 +0xb9
      github.com/cenkalti/rain/internal/announcer.announce()
          /var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/internal/announcer/announce.go:24 +0x18f
      github.com/cenkalti/rain/internal/announcer.(*PeriodicalAnnouncer).announce()
          /var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/internal/announcer/periodic.go:244 +0x1fc
      github.com/cenkalti/rain/internal/announcer.(*PeriodicalAnnouncer).doAnnounce·dwrap·5()
          /var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/internal/announcer/periodic.go:238 +0x6e
    
    Previous write at 0x00c000666678 by goroutine 151:
      github.com/cenkalti/rain/internal/tracker.(*Tier).Announce()
          /var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/internal/tracker/tier.go:29 +0x1c4
      github.com/cenkalti/rain/internal/announcer.announce()
          /var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/internal/announcer/announce.go:24 +0x18f
      github.com/cenkalti/rain/internal/announcer.(*PeriodicalAnnouncer).announce()
          /var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/internal/announcer/periodic.go:244 +0x1fc
      github.com/cenkalti/rain/internal/announcer.(*PeriodicalAnnouncer).doAnnounce·dwrap·5()
          /var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/internal/announcer/periodic.go:238 +0x6e
    
    Goroutine 81 (running) created at:
      github.com/cenkalti/rain/internal/announcer.(*PeriodicalAnnouncer).doAnnounce()
          /var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/internal/announcer/periodic.go:238 +0x110
      github.com/cenkalti/rain/internal/announcer.(*PeriodicalAnnouncer).Run()
          /var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/internal/announcer/periodic.go:209 +0x10ec
      github.com/cenkalti/rain/torrent.(*torrent).startNewAnnouncer·dwrap·45()
          /var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/torrent/torrent_start.go:107 +0x39
    
    Goroutine 151 (finished) created at:
      github.com/cenkalti/rain/internal/announcer.(*PeriodicalAnnouncer).doAnnounce()
          /var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/internal/announcer/periodic.go:238 +0x110
      github.com/cenkalti/rain/internal/announcer.(*PeriodicalAnnouncer).Run()
          /var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/internal/announcer/periodic.go:156 +0x284
      github.com/cenkalti/rain/torrent.(*torrent).startNewAnnouncer·dwrap·45()
          /var/lib/jenkins/go/pkg/mod/github.com/cenkalti/[email protected]/torrent/torrent_start.go:107 +0x39
    ==================
    

    If I read this right, the problem is in this file

    // Announce a torrent to the tracker.
    // If annouce fails, the next announce will be made to the next Tracker in the tier.
    func (t *Tier) Announce(ctx context.Context, req AnnounceRequest) (*AnnounceResponse, error) {
        resp, err := t.Trackers[t.index].Announce(ctx, req) // line 27
        if err != nil {
            t.index = (t.index + 1) % len(t.Trackers) // line 29
        }
        return resp, err
    }
    

    on line 27 and 29 we are reading/writing t.index. Maybe a fix would be to make t.index an atomic int, and use atomic operations to get/set it ?

    Or maybe the problem is with the t.Trackers array ? I will try to something obvious (like adding a mutex to Tier) to debug this further.

  • Add completion command hook

    Add completion command hook

    This change adds an optional torrent completion command hook that executes a shell command defined in the server configuration (oncompletecmd). The executed command's shell environment is provided with specific variables relating to the completed torrent:

    • RAIN_TORRENT_ADDED: the torrent adding date (UNIX timestamp)
    • RAIN_TORRENT_DIR: the torrent download directory location
    • RAIN_TORRENT_HASH: the torrent info hash
    • RAIN_TORRENT_ID: the torrent internal ID in Rain
    • RAIN_TORRENT_NAME: the torrent name

    Implements #20.

  • Expose more details about torrent files

    Expose more details about torrent files

    Hi, I'm very interested in using this software, however I find it a bit terse regarding the files downloaded via the torrents. Could it be possible to expose more information via the RPC, such as file-level statistics (e.g. file list, size, % completion etc)? I'm thinking of trying to implement this in a fork and submit it to the original project for upstream integration if you're interested: if so, do you have tips as to where to start looking in the codebase?

    Thanks! 😊

BitTorrent client in Go

wgo - Simple BitTorrent client in Go Roger Pau Monné (2010 - 2011) Introduction This project is based on the previous work of jackpal, Taipei-Torrent:

Jan 2, 2020
BitTorrent DHT Protocol && DHT Spider.
BitTorrent DHT Protocol && DHT Spider.

See the video on the Youtube. 中文版README Introduction DHT implements the bittorrent DHT protocol in Go. Now it includes: BEP-3 (part) BEP-5 BEP-9 BEP-1

Dec 20, 2022
Handshake Query is a cross-platform library to trustlessly resolve and verify Handshake names using a p2p light client

Handshake Query ⚠️ Usage of this library is not currently recommended in your application as the API will likely change. Handshake Query is a cross-pl

Dec 22, 2022
DEPRECATED (moved to tendermint/tendermint): Golang P2P library

tendermint/go-p2p tendermint/go-p2p provides an abstraction around peer-to-peer communication. Peer/MConnection/Channel Each peer has one MConnection

Nov 9, 2022
An experimental project to build a framework for naming and sharing files and other data securely
An experimental project to build a framework for naming and sharing files and other data securely

Upspin Documentation: upspin.io About the project Upspin is an experimental project to build a framework for naming and sharing files and other data s

Oct 20, 2021
oDrop, a fast efficient cross-platform file transfer software for server and home environments

oDrop is a cross-platform LAN file transfer software to efficiently transfer files between computers, oDrop is useful in environments where GUI is not available.

Jun 4, 2022
JuiceFS is a distributed POSIX file system built on top of Redis and S3.
JuiceFS is a distributed POSIX file system built on top of Redis and S3.

JuiceFS is an open-source POSIX file system built on top of Redis and object storage

Jan 5, 2023
A web based drag and drop file transfer tool for sending files across the internet.

DnD A file transfer tool. Demo Usage Get go get github.com/0xcaff/dnd or download the latest release (you don't need go to run it) Run dnd Now navig

Dec 16, 2022
Send and receive files securely through Tor.
Send and receive files securely through Tor.

onionbox A basic implementation of OnionShare in Go. Mostly built as a fun project, onionbox is still a WIP so usage is not guaranteed secure, yet. Ke

Nov 22, 2022
proxyd proxies data between TCP, TLS, and unix sockets

proxyd proxyd proxies data between TCP, TLS, and unix sockets TLS termination: Connecting to a remote application's unix socket: +---------+

Nov 9, 2022
transfer.sh - Easy and fast file sharing from the command-line.

Easy and fast file sharing from the command-line. This code contains the server with everything you need to create your own instance.

Jan 2, 2023
Easy and fast file sharing from the command-line.

Easy and fast file sharing from the command-line. This code contains the server with everything you need to create your own instance.

Jan 2, 2023
Wormhole-gui is a cross-platform application that lets you easily share files, folders and text between devices.
Wormhole-gui is a cross-platform application that lets you easily share files, folders and text between devices.

Cross-platform application for easy encrypted sharing of files, folders, and text between devices.

Dec 30, 2022
Distributed File Store Application Consist of API Server to handle file operations and command line tool to do operations

Filestore Distributed File Store Application Consist of API Server to handle file operations and command line tool to do operations (store named binar

Nov 7, 2021
aqua is a simple file uploading and sharing server for personal use.
aqua is a simple file uploading and sharing server for personal use.

aqua is a simple file uploading and sharing server for personal use. It is built to be easy to set up and host on your own server, for example to use it in combination with uploading tools like ShareX.

Jul 7, 2022
Transfer - A simple go application for uploading, downloading and checksumming of files

Transfer This project holds a simple go application for uploading, downloading a

Aug 18, 2022
garlicshare is an open source tool that lets you securely and anonymously share files on a hosted onion service using the Tor network.
garlicshare is an open source tool that lets you securely and anonymously share files on a hosted onion service using the Tor network.

garlicshare is an open source tool that lets you securely and anonymously share files on a hosted onion service using the Tor network.

Dec 22, 2022
Simple temporary file upload and transfer web application coding with Go language.

Temp File Transfer Web Application Simple temporary file upload and transfer web application coding with Go language. Explore the Golang » Live Demo T

Dec 2, 2022
🖥 Securely transfer and send anything between computers with TUI.
🖥 Securely transfer and send anything between computers with TUI.

??️ Securely transfer and send anything between computers with TUI. Installation ways

Dec 21, 2022