initial
This commit is contained in:
153
reseeder.go
Normal file
153
reseeder.go
Normal file
@@ -0,0 +1,153 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/braintree/manners"
|
||||
"github.com/gorilla/handlers"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var netdbDir = flag.String("dir", "./netdb", "Location of your netdb directory")
|
||||
var bindIp = flag.String("ip", "", "Interface to bind to")
|
||||
var bindPort = flag.String("port", "3000", "Port to bind to")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
netdb := NewNetDb(*netdbDir)
|
||||
reseeder := &Reseeder{netdb, make([]*Peer, 100)}
|
||||
|
||||
log.Printf("Starting server on %s:%s serving netdb from %s", *bindIp, *bindPort, *netdbDir)
|
||||
|
||||
server := manners.NewServer()
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
go func() {
|
||||
<-c
|
||||
log.Println("waiting for connections to close and exiting...")
|
||||
server.Shutdown <- true
|
||||
go time.AfterFunc(time.Duration(5)*time.Second, func() {
|
||||
log.Println("Killing idle connections...")
|
||||
os.Exit(0)
|
||||
})
|
||||
}()
|
||||
|
||||
err := server.ListenAndServe(*bindIp+":"+*bindPort, handlers.CombinedLoggingHandler(os.Stdout, reseeder))
|
||||
if err != nil {
|
||||
log.Fatal("ListenAndServe: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
type Reseeder struct {
|
||||
NetDb *NetDb
|
||||
Peers []*Peer
|
||||
}
|
||||
|
||||
func (rs *Reseeder) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
infos := make(chan *RouterInfo)
|
||||
|
||||
peer := &Peer{req.RemoteAddr, time.Now(), time.Now()}
|
||||
|
||||
go rs.GetForPeer(peer, infos)
|
||||
|
||||
for info := range infos {
|
||||
fmt.Fprintf(w, "%s\n", info.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func (rs *Reseeder) GetForPeer(peer *Peer, infos chan *RouterInfo) {
|
||||
rs.NetDb.lock.RLock()
|
||||
defer rs.NetDb.lock.RUnlock()
|
||||
|
||||
for _, info := range rs.NetDb.RouterInfos {
|
||||
infos <- info
|
||||
}
|
||||
close(infos)
|
||||
}
|
||||
|
||||
func NewNetDb(dir string) *NetDb {
|
||||
if _, err := os.Stat(dir); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
log.Fatalf("netdb directory is not readable: %s", dir)
|
||||
} else {
|
||||
// other error
|
||||
}
|
||||
}
|
||||
netdb := &NetDb{Dir: dir, RouterInfos: make(map[string]*RouterInfo, 1000)}
|
||||
netdb.Refresh()
|
||||
|
||||
return netdb
|
||||
}
|
||||
|
||||
type NetDb struct {
|
||||
lock sync.RWMutex
|
||||
RouterInfos map[string]*RouterInfo
|
||||
Dir string
|
||||
}
|
||||
|
||||
func (db *NetDb) Refresh() {
|
||||
files, err := ioutil.ReadDir(db.Dir)
|
||||
if nil != err {
|
||||
log.Fatalf("unable to read %s", db.Dir)
|
||||
}
|
||||
for _, file := range files {
|
||||
db.Set(file.Name(), NewRouterInfo(db.Dir+file.Name()))
|
||||
}
|
||||
}
|
||||
|
||||
func (db *NetDb) Get(key string) (*RouterInfo, bool) {
|
||||
db.lock.RLock()
|
||||
defer db.lock.RUnlock()
|
||||
d, ok := db.RouterInfos[key]
|
||||
return d, ok
|
||||
}
|
||||
|
||||
func (db *NetDb) Set(key string, d *RouterInfo) {
|
||||
db.lock.Lock()
|
||||
defer db.lock.Unlock()
|
||||
db.RouterInfos[key] = d
|
||||
}
|
||||
|
||||
func (db *NetDb) UnSet(key string) {
|
||||
db.lock.Lock()
|
||||
defer db.lock.Unlock()
|
||||
delete(db.RouterInfos, key)
|
||||
}
|
||||
|
||||
func NewRouterInfo(file string) *RouterInfo {
|
||||
return &RouterInfo{file}
|
||||
}
|
||||
|
||||
type RouterInfo struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
type Peer struct {
|
||||
Ip string
|
||||
Seen time.Time
|
||||
Created time.Time
|
||||
}
|
||||
|
||||
//// stuff for reverse proxy handling
|
||||
func proxiedHandler(h http.Handler) http.Handler {
|
||||
return remoteAddrFixup{h}
|
||||
}
|
||||
|
||||
type remoteAddrFixup struct {
|
||||
h http.Handler
|
||||
}
|
||||
|
||||
func (h remoteAddrFixup) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if prior, ok := r.Header["X-Forwarded-For"]; ok {
|
||||
r.RemoteAddr = prior[0]
|
||||
}
|
||||
h.h.ServeHTTP(w, r)
|
||||
}
|
||||
Reference in New Issue
Block a user