Skip to content

Commit

Permalink
Initial commit of code
Browse files Browse the repository at this point in the history
  • Loading branch information
gombadi committed Aug 16, 2015
1 parent 23ffc3d commit ff9766d
Show file tree
Hide file tree
Showing 361 changed files with 112,814 additions and 0 deletions.
86 changes: 86 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,88 @@
# dnsseeder
Go Language dns seeder for the Twister P2P network

This is a dns seeder for the [Twister P2P network](http://twister.net.co/)

It is based on the original twister-seeder https://github.com/miguelfreitas/twister-seeder



> **NOTE:** This repository is under ongoing development and
is likely to break over time. Use at your own risk.


## Installing

Simply use go get to download the code:

$ go get github.com/gombadi/dnsseeder

Dependencies are handled by the Go vendor directory.

Note: This means the codebase requires Go 1.5 or higher and use of GO15VENDOREXPERIMENT=1


## Usage

$ dnsseeder -h <domain respond to>

An easy way to run the program is with tmux or screen. This enables you to log out and leave the program running.

```
Command line Options:
-h hostname to serve
-p port to listen on
-d Produce debug output
-v Produce verbose output
-v Produce stats output
```

An easy way to run the program is with the following script. Change to suit your system.

```
#!/bin/bash
LOGDIR=${HOME}/goseederlogs/
mkdir -p ${LOGDIR}
# pass through the logging level needed
if [ -z ${1} ]; then
LOGLV="-v"
else
LOGLV="${1}"
fi
cd
echo
echo "======= Run the Go Language dnsseed ======="
echo
${HOME}/go/bin/dnsseeder -h <host.to.serve> -p <port.to.listen.on> ${LOGLV} 2>&1 | tee ${LOGDIR}/$(date +%F-%s)-goseeder.log
```


## RUNNING AS NON-ROOT

Typically, you'll need root privileges to listen to port 53 (name service).

One solution is using an iptables rule (Linux only) to redirect it to
a non-privileged port:

$ iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-port 5353

If properly configured, this will allow you to run dnsseeder in userspace, using
the -p 5353 option.


## License

For the DNS library license see https://github.com/miekg/dns

For the bitcoin library license see https://github.com/btcsuite/btcd


234 changes: 234 additions & 0 deletions crawler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
package main

import (
"errors"
"log"
"net"
"strconv"
"time"

"github.com/btcsuite/btcd/wire"
)

// crawlTwistee runs in a goroutine, crawls the remote ip and updates the master
// list of currently active addresses
func crawlTwistee(tw *Twistee) {

if config.debug {
log.Printf("status - start crawl: twistee %s status: %v:%v lastcrawl: %s\n",
net.JoinHostPort(tw.na.IP.String(),
strconv.Itoa(int(tw.na.Port))),
tw.status,
tw.rating,
time.Since(tw.crawlStart).String())
}

tw.crawlActive = true
tw.crawlStart = time.Now()

defer crawlEnd(tw)

// connect to the remote ip and ask them for their addr list
ras, err := crawlIP(tw)
if err != nil {
// update the fact that we have not connected to this twistee
tw.lastTry = time.Now()
tw.connectFails++
// update the status of this failed twistee
switch tw.status {
case statusRG:
if tw.rating += 25; tw.rating > 30 {
tw.status = statusWG
}
case statusCG:
if tw.rating += 25; tw.rating >= 50 {
tw.status = statusWG
}
case statusWG:
if tw.rating += 30; tw.rating >= 100 {
tw.status = statusNG // not able to connect to this twistee so ignore
}
}
// no more to do so return which will shutdown the goroutine & call
// the deffered cleanup
if config.verbose {
log.Printf("debug - failed crawl: twistee %s newstatus: %v:%v\n",
net.JoinHostPort(tw.na.IP.String(),
strconv.Itoa(int(tw.na.Port))),
tw.status,
tw.rating)
}
return
}

// succesful connection and addresses received so mark status
if tw.status != statusCG {
tw.status = statusCG
}
tw.rating = 0
tw.connectFails = 0
tw.lastConnect = time.Now()
tw.lastTry = time.Now()

added := 0

// loop through all the received network addresses and add to thelist if not present
for _, na := range ras {
// a new network address so add to the system
if x := config.seeder.addNa(na); x == true {
added++
}
}

if config.verbose {
log.Printf("status - crawl done: twistee: %s newstatus: %v.%v received_addr: %v added_addr: %v CrawlTime: %s\n",
net.JoinHostPort(tw.na.IP.String(),
strconv.Itoa(int(tw.na.Port))),
tw.status,
tw.rating,
len(ras),
added,
time.Since(tw.crawlStart).String())
}

// goroutine ends. deffered cleanup runs
}

// crawlEnd is a deffered func to update theList after a crawl is all done
func crawlEnd(tw *Twistee) {
tw.crawlActive = false
// FIXME - scan for long term crawl active twistees. Dial timeout is 10 seconds
// so should be done in under 5 minutes
}

// crawlIP retrievs a slice of ip addresses from a client
func crawlIP(tw *Twistee) ([]*wire.NetAddress, error) {

ip := tw.na.IP.String()
port := strconv.Itoa(int(tw.na.Port))
// get correct formatting for ipv6 addresses
dialString := net.JoinHostPort(ip, port)

conn, err := net.DialTimeout("tcp", dialString, time.Second*10)
if err != nil {
if config.debug {
log.Printf("error - Could not connect to %s - %v\n", ip, err)
}
return nil, err
}

defer conn.Close()
if config.verbose {
log.Printf("%s - Connected to remote address. Last connect was %v ago\n", ip, time.Since(tw.lastConnect).String())
}

// First command to remote end needs to be a version command
// last parameter is lastblock
msgver, err := wire.NewMsgVersionFromConn(conn, NOUNCE, 0)
if err != nil {
log.Printf("error - NewMsgVer from conn: %v\n", err)
return nil, err
}

err = wire.WriteMessage(conn, msgver, PVER, TWISTNET)
if err != nil {
// Log and handle the error
log.Printf("error - %s:%s Write Message: %v\n", ip, port, err)
return nil, err
}

// first message received should be version
msg, _, err := wire.ReadMessage(conn, PVER, TWISTNET)
if err != nil {
// Log and handle the error
log.Printf("error - %s:%s Read Message after sending version: %v\n", ip, port, err)
return nil, err
}

switch msg := msg.(type) {
case *wire.MsgVersion:
// The message is a pointer to a MsgVersion struct.
if config.debug {
log.Printf("%s - Remote version: %v\n", ip, msg.ProtocolVersion)
}
default:
if config.debug {
log.Printf("error: expected Version Message but received: %v\n", msg.Command())
}
return nil, errors.New("Error. Did not receive expected Version message from remote client")
}

// FIXME - update twistee client version with what they just said

// send verack command
msgverack := wire.NewMsgVerAck()

err = wire.WriteMessage(conn, msgverack, PVER, TWISTNET)
if err != nil {
// Log and handle the error
log.Printf("error - %s:%s Writing Message Ver Ack failed: %v\n", ip, port, err)
return nil, err
}

// second message received should be verack
msg, _, err = wire.ReadMessage(conn, PVER, TWISTNET)
if err != nil {
// Log and handle the error
log.Printf("error - %s:%s Reading Message expected Ver Ack: %v\n", ip, port, err)
return nil, err
}

switch msg := msg.(type) {
case *wire.MsgVerAck:
if config.debug {
// The message is a pointer to a MsgVersion struct.
log.Printf("%s - received Version Ack\n", ip)
}
default:
if config.debug {
log.Printf("error: expected Version Ack Message but received: %v\n", msg.Command())
}
return nil, errors.New("Error. Did not receive expected Version Ack message from remote client")
}

// send getaddr command
msgGetAddr := wire.NewMsgGetAddr()

err = wire.WriteMessage(conn, msgGetAddr, PVER, TWISTNET)
if err != nil {
// Log and handle the error
log.Printf("error - %s:%s writing message Get Addr: %v\n", ip, port, err)
return nil, err
}

dowhile := true
for dowhile == true {

// Using the Bitcoin lib for the Twister Net means it does not understand some
// of the commands and will error. We can ignore these as we are only
// interested in the addr message and its content.
msgaddr, _, _ := wire.ReadMessage(conn, PVER, TWISTNET)
if msgaddr != nil {
switch msg := msgaddr.(type) {
case *wire.MsgAddr:
// received the addrt message so return the result
if config.debug {
log.Printf("%s - received valid addr message\n", ip)
}
return msg.AddrList, nil
dowhile = false
default:
if config.debug {
log.Printf("%s - ignoring message - %v\n", ip, msg.Command())
}
}
}
}

// should never get here but need a return command
return nil, nil
}

/*
*/
Loading

0 comments on commit ff9766d

Please sign in to comment.