merge majestrate's changes from years ago
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@
|
||||
*.coverprofile
|
||||
*exportable-fuzz.zip
|
||||
go-i2p
|
||||
*.exe
|
25
Makefile
Normal file
25
Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
REPO := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
|
||||
ifdef GOROOT
|
||||
GO = $(GOROOT)/bin/go
|
||||
endif
|
||||
|
||||
GO ?= $(shell which go)
|
||||
|
||||
ifeq ($(GOOS),windows)
|
||||
EXE := $(REPO)/go-i2p.exe
|
||||
else
|
||||
EXE := $(REPO)/go-i2p
|
||||
endif
|
||||
|
||||
build: clean $(EXE)
|
||||
|
||||
$(EXE):
|
||||
$(GO) build -v -o $(EXE)
|
||||
|
||||
test:
|
||||
$(GO) test ./...
|
||||
|
||||
clean:
|
||||
$(GO) clean -v
|
@ -56,7 +56,7 @@ func (certificate Certificate) Type() (cert_type int, err error) {
|
||||
cert_len := len(certificate)
|
||||
if cert_len < CERT_MIN_SIZE {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Certificate) Type",
|
||||
"at": "(Certificate) Type",
|
||||
"certificate_bytes_length": cert_len,
|
||||
"reason": "too short (len < CERT_MIN_SIZE)",
|
||||
}).Error("invalid certificate")
|
||||
@ -82,7 +82,7 @@ func (certificate Certificate) Length() (length int, err error) {
|
||||
inferred_len := length + CERT_MIN_SIZE
|
||||
if inferred_len > cert_len {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Certificate) Length",
|
||||
"at": "(Certificate) Length",
|
||||
"certificate_bytes_length": cert_len,
|
||||
"certificate_length_field": length,
|
||||
"expected_bytes_length": inferred_len,
|
||||
@ -91,7 +91,7 @@ func (certificate Certificate) Length() (length int, err error) {
|
||||
err = errors.New("certificate parsing warning: certificate data is shorter than specified by length")
|
||||
} else if cert_len > inferred_len {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Certificate) Length",
|
||||
"at": "(Certificate) Length",
|
||||
"certificate_bytes_length": cert_len,
|
||||
"certificate_length_field": length,
|
||||
"expected_bytes_length": inferred_len,
|
||||
|
@ -28,8 +28,8 @@ payload :: data
|
||||
|
||||
import (
|
||||
"errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/go-i2p/go-i2p/lib/crypto"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Key Certificate Signing Key Types
|
||||
@ -90,6 +90,10 @@ func (key_certificate KeyCertificate) Data() ([]byte, error) {
|
||||
func (key_certificate KeyCertificate) SigningPublicKeyType() (signing_pubkey_type int, err error) {
|
||||
data, err := key_certificate.Data()
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(KeyCertificate) SigningPublicKeyType",
|
||||
"reason": err.Error(),
|
||||
}).Error("error getting signing public key")
|
||||
return
|
||||
}
|
||||
data_len := len(data)
|
||||
@ -231,6 +235,11 @@ func (key_certificate KeyCertificate) SignatureSize() (size int) {
|
||||
}
|
||||
key_type, err := key_certificate.SigningPublicKeyType()
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(KeyCertificate) SignatureSize",
|
||||
"key_type": key_type,
|
||||
"reason": "failed to read signing public key type",
|
||||
}).Error("error getting signature size")
|
||||
return 0
|
||||
}
|
||||
return sizes[int(key_type)]
|
||||
|
@ -47,8 +47,8 @@ total length: 387+ bytes
|
||||
|
||||
import (
|
||||
"errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/go-i2p/go-i2p/lib/crypto"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Sizes of various KeysAndCert structures and requirements
|
||||
|
@ -82,8 +82,8 @@ signature :: Signature
|
||||
|
||||
import (
|
||||
"errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/go-i2p/go-i2p/lib/crypto"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Sizes of various structures in an I2P LeaseSet
|
||||
|
@ -51,7 +51,7 @@ func (mapping Mapping) Values() (map_values MappingValues, errs []error) {
|
||||
mapping_len := len(mapping)
|
||||
if mapping_len > inferred_length {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"at": "(Mapping) Values",
|
||||
"mappnig_bytes_length": mapping_len,
|
||||
"mapping_length_field": length,
|
||||
"expected_bytes_length": inferred_length,
|
||||
@ -60,7 +60,7 @@ func (mapping Mapping) Values() (map_values MappingValues, errs []error) {
|
||||
errs = append(errs, errors.New("warning parsing mapping: data exists beyond length of mapping"))
|
||||
} else if inferred_length > mapping_len {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"at": "(Mapping) Values",
|
||||
"mappnig_bytes_length": mapping_len,
|
||||
"mapping_length_field": length,
|
||||
"expected_bytes_length": inferred_length,
|
||||
|
@ -204,13 +204,15 @@ func (router_info RouterInfo) Options() (mapping Mapping) {
|
||||
}
|
||||
|
||||
//
|
||||
// Return the 40 bytes that follow the Mapping in the RouterInfo.
|
||||
// Return the signature of this router info
|
||||
//
|
||||
func (router_info RouterInfo) Signature() (signature Signature) {
|
||||
head := router_info.optionsLocation()
|
||||
size := head + router_info.optionsSize()
|
||||
// TODO: signature is not always 40 bytes, is 40 bytes for DSA only
|
||||
signature = Signature(router_info[size : size+40])
|
||||
ident, _ := router_info.RouterIdentity()
|
||||
keyCert := KeyCertificate(ident)
|
||||
sigSize := keyCert.SignatureSize()
|
||||
signature = Signature(router_info[size : size+sigSize])
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ func (str String) Length() (length int, err error) {
|
||||
str_len := len(str)
|
||||
if inferred_len > str_len {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(String) Length",
|
||||
"at": "(String) Length",
|
||||
"string_bytes_length": str_len,
|
||||
"string_length_field": length,
|
||||
"expected_bytes_length": inferred_len,
|
||||
@ -45,7 +45,7 @@ func (str String) Length() (length int, err error) {
|
||||
err = errors.New("string parsing warning: string data is shorter than specified by length")
|
||||
} else if str_len > inferred_len {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(String) Length",
|
||||
"at": "(String) Length",
|
||||
"string_bytes_length": str_len,
|
||||
"string_length_field": length,
|
||||
"expected_bytes_length": inferred_len,
|
||||
|
@ -2,8 +2,8 @@ package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/go-i2p/go-i2p/lib/common"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
@ -41,14 +41,14 @@ var SU3_CONTENT_TYPE_NEWS_FEED = "news_feed"
|
||||
var SU3_CONTENT_TYPE_BLOCKLIST_FEED = "blocklist_feed"
|
||||
|
||||
var SU3_SIGNATURE_TYPE_MAP = map[[SU3_SIGNATURE_TYPE_LEN]byte]string{
|
||||
[SU3_SIGNATURE_TYPE_LEN]byte{0x00, 0x00}: SU3_SIGNATURE_TYPE_DSA_SHA1,
|
||||
[SU3_SIGNATURE_TYPE_LEN]byte{0x00, 0x01}: SU3_SIGNATURE_TYPE_ECDSA_SHA256_P256,
|
||||
[SU3_SIGNATURE_TYPE_LEN]byte{0x00, 0x02}: SU3_SIGNATURE_TYPE_ECDSA_SHA384_P384,
|
||||
[SU3_SIGNATURE_TYPE_LEN]byte{0x00, 0x03}: SU3_SIGNATURE_TYPE_ECDSA_SHA512_P521,
|
||||
[SU3_SIGNATURE_TYPE_LEN]byte{0x00, 0x04}: SU3_SIGNATURE_TYPE_RSA_SHA256_2048,
|
||||
[SU3_SIGNATURE_TYPE_LEN]byte{0x00, 0x05}: SU3_SIGNATURE_TYPE_RSA_SHA384_3072,
|
||||
[SU3_SIGNATURE_TYPE_LEN]byte{0x00, 0x06}: SU3_SIGNATURE_TYPE_RSA_SHA512_4096,
|
||||
[SU3_SIGNATURE_TYPE_LEN]byte{0x00, 0x08}: SU3_SIGNATURE_TYPE_EdDSA_SHA512_Ed25519ph,
|
||||
{0x00, 0x00}: SU3_SIGNATURE_TYPE_DSA_SHA1,
|
||||
{0x00, 0x01}: SU3_SIGNATURE_TYPE_ECDSA_SHA256_P256,
|
||||
{0x00, 0x02}: SU3_SIGNATURE_TYPE_ECDSA_SHA384_P384,
|
||||
{0x00, 0x03}: SU3_SIGNATURE_TYPE_ECDSA_SHA512_P521,
|
||||
{0x00, 0x04}: SU3_SIGNATURE_TYPE_RSA_SHA256_2048,
|
||||
{0x00, 0x05}: SU3_SIGNATURE_TYPE_RSA_SHA384_3072,
|
||||
{0x00, 0x06}: SU3_SIGNATURE_TYPE_RSA_SHA512_4096,
|
||||
{0x00, 0x08}: SU3_SIGNATURE_TYPE_EdDSA_SHA512_Ed25519ph,
|
||||
}
|
||||
|
||||
var SU3_FILE_TYPE_MAP = map[byte]string{
|
||||
@ -242,7 +242,7 @@ func getFileFormatVersion(data []byte) (int, error) {
|
||||
|
||||
if file_format_version_byte := data[SU3_MAGIC_BYTE_LEN+1]; file_format_version_byte != 0x00 {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "config.getSignatureType",
|
||||
"at": "config.getSignatureType",
|
||||
"file_format_version_byte": file_format_version_byte,
|
||||
}).Debug(ERR_SU3_FILE_FORMAT_VERSION_UNKNOWN)
|
||||
return int(file_format_version_byte), ERR_SU3_FILE_FORMAT_VERSION_UNKNOWN
|
||||
|
@ -14,7 +14,7 @@ func TestDSA(t *testing.T) {
|
||||
sk, err = sk.Generate()
|
||||
if err == nil {
|
||||
zeros := 0
|
||||
for b, _ := range sk {
|
||||
for b := range sk {
|
||||
if b == 0 {
|
||||
zeros++
|
||||
}
|
||||
|
@ -9,11 +9,11 @@ import (
|
||||
// XXX: IMPLEMENT THIS
|
||||
func Test_I2PHMAC(t *testing.T) {
|
||||
data := make([]byte, 64)
|
||||
for idx, _ := range data {
|
||||
for idx := range data {
|
||||
data[idx] = 1
|
||||
}
|
||||
var k HMACKey
|
||||
for idx, _ := range k[:] {
|
||||
for idx := range k[:] {
|
||||
k[idx] = 1
|
||||
}
|
||||
d := I2PHMAC(data, k)
|
||||
|
@ -2,9 +2,9 @@ package i2np
|
||||
|
||||
import (
|
||||
"errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/go-i2p/go-i2p/lib/common"
|
||||
"github.com/go-i2p/go-i2p/lib/tunnel"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -2,8 +2,8 @@ package i2np
|
||||
|
||||
import (
|
||||
"errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/go-i2p/go-i2p/lib/common"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -30,6 +30,9 @@ type NetworkDatabase interface {
|
||||
// return how many router infos we have
|
||||
Size() int
|
||||
|
||||
// Recaculate size of netdb from backend
|
||||
RecalculateSize() error
|
||||
|
||||
// ensure underlying resources exist , i.e. directories, files, configs
|
||||
Ensure() error
|
||||
}
|
||||
|
@ -3,13 +3,17 @@ package netdb
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/go-i2p/go-i2p/lib/bootstrap"
|
||||
"github.com/go-i2p/go-i2p/lib/common"
|
||||
"github.com/go-i2p/go-i2p/lib/common/base64"
|
||||
"github.com/go-i2p/go-i2p/lib/util"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// standard network database implementation using local filesystem skiplist
|
||||
@ -45,6 +49,60 @@ func (db StdNetDB) Path() string {
|
||||
// return how many routers we know about in our network database
|
||||
//
|
||||
func (db StdNetDB) Size() (routers int) {
|
||||
// TODO: implement this
|
||||
var err error
|
||||
var data []byte
|
||||
if !util.CheckFileExists(db.cacheFilePath()) {
|
||||
// regenerate
|
||||
err = db.RecalculateSize()
|
||||
if err != nil {
|
||||
// TODO : what now? let's panic for now
|
||||
util.Panicf("could not recalculate netdb size: %s", err)
|
||||
}
|
||||
}
|
||||
data, err = ioutil.ReadFile(db.cacheFilePath())
|
||||
if err == nil {
|
||||
routers, err = strconv.Atoi(string(data))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// name of file to hold precomputed size of netdb
|
||||
const CacheFileName = "sizecache.txt"
|
||||
|
||||
// get filepath for storing netdb info cache
|
||||
func (db StdNetDB) cacheFilePath() string {
|
||||
return filepath.Join(db.Path(), CacheFileName)
|
||||
}
|
||||
|
||||
func (db StdNetDB) CheckFilePathValid(fpath string) bool {
|
||||
// TODO: make this better
|
||||
return strings.HasSuffix(fpath, ".dat")
|
||||
}
|
||||
|
||||
// recalculateSize recalculates cached size of netdb
|
||||
func (db StdNetDB) RecalculateSize() (err error) {
|
||||
fpath := db.cacheFilePath()
|
||||
count := 0
|
||||
err = filepath.Walk(fpath, func(fname string, info os.FileInfo, err error) error {
|
||||
if info.IsDir() {
|
||||
return err
|
||||
}
|
||||
if db.CheckFilePathValid(fname) {
|
||||
// TODO: make sure it's in a skiplist directory
|
||||
count++
|
||||
}
|
||||
return err
|
||||
})
|
||||
if err == nil {
|
||||
str := fmt.Sprintf("%d", count)
|
||||
var f *os.File
|
||||
f, err = os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err == nil {
|
||||
_, err = io.WriteString(f, str)
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -3,12 +3,16 @@ package router
|
||||
import (
|
||||
"github.com/go-i2p/go-i2p/lib/config"
|
||||
"github.com/go-i2p/go-i2p/lib/netdb"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"time"
|
||||
)
|
||||
|
||||
// i2p router type
|
||||
type Router struct {
|
||||
cfg *config.RouterConfig
|
||||
ndb netdb.StdNetDB
|
||||
cfg *config.RouterConfig
|
||||
ndb netdb.StdNetDB
|
||||
closeChnl chan bool
|
||||
running bool
|
||||
}
|
||||
|
||||
// create router with default configuration
|
||||
@ -22,15 +26,58 @@ func CreateRouter() (r *Router, err error) {
|
||||
func FromConfig(c *config.RouterConfig) (r *Router, err error) {
|
||||
r = new(Router)
|
||||
r.cfg = c
|
||||
r.closeChnl = make(chan bool)
|
||||
return
|
||||
}
|
||||
|
||||
// Wait blocks until router is fully stopped
|
||||
func (r *Router) Wait() {
|
||||
<-r.closeChnl
|
||||
}
|
||||
|
||||
// Stop starts stopping internal state of router
|
||||
func (r *Router) Stop() {
|
||||
r.closeChnl <- true
|
||||
r.running = false
|
||||
}
|
||||
|
||||
// Close closes any internal state and finallizes router resources so that nothing can start up again
|
||||
func (r *Router) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Start starts router mainloop
|
||||
func (r *Router) Start() {
|
||||
if r.running {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Router) Start",
|
||||
"reason": "router is already running",
|
||||
}).Error("Error Starting router")
|
||||
return
|
||||
}
|
||||
r.running = true
|
||||
go r.mainloop()
|
||||
}
|
||||
|
||||
// run i2p router mainloop
|
||||
func (r *Router) Run() {
|
||||
func (r *Router) mainloop() {
|
||||
r.ndb = netdb.StdNetDB(r.cfg.NetDb.Path)
|
||||
// make sure the netdb is ready
|
||||
err := r.ndb.Ensure()
|
||||
if err == nil {
|
||||
// netdb ready
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Router) mainloop",
|
||||
}).Info("Router ready")
|
||||
for err == nil {
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
} else {
|
||||
// netdb failed
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Router) mainloop",
|
||||
"reason": err.Error(),
|
||||
}).Error("Netdb Startup failed")
|
||||
r.Stop()
|
||||
}
|
||||
}
|
||||
|
6
lib/transport/ntcp/session.go
Normal file
6
lib/transport/ntcp/session.go
Normal file
@ -0,0 +1,6 @@
|
||||
package ntcp
|
||||
|
||||
// Session implements TransportSession
|
||||
// An established transport session
|
||||
type Session struct {
|
||||
}
|
5
lib/transport/ntcp/transport.go
Normal file
5
lib/transport/ntcp/transport.go
Normal file
@ -0,0 +1,5 @@
|
||||
package ntcp
|
||||
|
||||
// Transport is an ntcp transport implementing transport.Transport interface
|
||||
type Transport struct {
|
||||
}
|
@ -3,8 +3,8 @@ package tunnel
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/go-i2p/go-i2p/lib/common"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
/*
|
||||
|
@ -2,8 +2,8 @@ package tunnel
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/go-i2p/go-i2p/lib/crypto"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
/*
|
||||
|
12
lib/util/checkfile.go
Normal file
12
lib/util/checkfile.go
Normal file
@ -0,0 +1,12 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// Check if a file exists and is readable etc
|
||||
// returns false if not
|
||||
func CheckFileExists(fpath string) bool {
|
||||
_, e := os.Stat(fpath)
|
||||
return e == nil
|
||||
}
|
16
lib/util/closeables.go
Normal file
16
lib/util/closeables.go
Normal file
@ -0,0 +1,16 @@
|
||||
package util
|
||||
|
||||
import "io"
|
||||
|
||||
var closeOnExit []io.Closer
|
||||
|
||||
func RegisterCloser(c io.Closer) {
|
||||
closeOnExit = append(closeOnExit, c)
|
||||
}
|
||||
|
||||
func CloseAll() {
|
||||
for idx := range closeOnExit {
|
||||
closeOnExit[idx].Close()
|
||||
}
|
||||
closeOnExit = nil
|
||||
}
|
11
lib/util/panicf.go
Normal file
11
lib/util/panicf.go
Normal file
@ -0,0 +1,11 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Panicf allows passing formated string to panic()
|
||||
func Panicf(format string, args ...interface{}) {
|
||||
s := fmt.Sprintf(format, args...)
|
||||
panic(s)
|
||||
}
|
33
lib/util/signals/signals.go
Normal file
33
lib/util/signals/signals.go
Normal file
@ -0,0 +1,33 @@
|
||||
package signals
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
var sigChan = make(chan os.Signal)
|
||||
|
||||
type Handler func()
|
||||
|
||||
var reloaders []Handler
|
||||
|
||||
func RegisterReloadHandler(f Handler) {
|
||||
reloaders = append(reloaders, f)
|
||||
}
|
||||
|
||||
func handleReload() {
|
||||
for idx := range reloaders {
|
||||
reloaders[idx]()
|
||||
}
|
||||
}
|
||||
|
||||
var interrupters []Handler
|
||||
|
||||
func RegisterInterruptHandler(f Handler) {
|
||||
interrupters = append(interrupters, f)
|
||||
}
|
||||
|
||||
func handleInterrupted() {
|
||||
for idx := range interrupters {
|
||||
interrupters[idx]()
|
||||
}
|
||||
}
|
30
lib/util/signals/unix.go
Normal file
30
lib/util/signals/unix.go
Normal file
@ -0,0 +1,30 @@
|
||||
// +build !windows
|
||||
|
||||
package signals
|
||||
|
||||
import (
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func init() {
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
|
||||
}
|
||||
|
||||
func Handle() {
|
||||
for {
|
||||
sig, ok := <-sigChan
|
||||
if !ok {
|
||||
// closed channel
|
||||
return
|
||||
}
|
||||
if sig == syscall.SIGHUP {
|
||||
handleReload()
|
||||
} else if sig == syscall.SIGINT || sig == syscall.SIGTERM {
|
||||
handleInterrupted()
|
||||
} else {
|
||||
// wtf?
|
||||
}
|
||||
}
|
||||
|
||||
}
|
28
lib/util/signals/windows.go
Normal file
28
lib/util/signals/windows.go
Normal file
@ -0,0 +1,28 @@
|
||||
// +build windows
|
||||
|
||||
package signals
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
)
|
||||
|
||||
func init() {
|
||||
signal.Notify(sigChan, os.Interrupt)
|
||||
}
|
||||
|
||||
func Handle() {
|
||||
for {
|
||||
sig, ok := <-sigChan
|
||||
if !ok {
|
||||
// closed channel
|
||||
return
|
||||
}
|
||||
if sig == os.Interrupt {
|
||||
handleInterrupted()
|
||||
} else {
|
||||
// wtf?
|
||||
}
|
||||
}
|
||||
|
||||
}
|
16
main.go
16
main.go
@ -1,18 +1,28 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/go-i2p/go-i2p/lib/router"
|
||||
"github.com/go-i2p/go-i2p/lib/util/signals"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
go signals.Handle()
|
||||
log.Info("parsing i2p router configuration")
|
||||
|
||||
log.Info("starting up i2p router")
|
||||
r, err := router.CreateRouter()
|
||||
if err == nil {
|
||||
r.Run()
|
||||
signals.RegisterReloadHandler(func() {
|
||||
// TODO: reload config
|
||||
})
|
||||
signals.RegisterInterruptHandler(func() {
|
||||
// TODO: graceful shutdown
|
||||
r.Stop()
|
||||
})
|
||||
r.Start()
|
||||
r.Wait()
|
||||
r.Close()
|
||||
} else {
|
||||
log.Errorf("failed to create i2p router: %s", err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user