"log"
"net"
"os"
+ "regexp"
"strconv"
"strings"
"time"
"github.com/dustin/go-humanize"
"go.cypherpunks.ru/nncp/v8"
+ nncpYggdrasil "go.cypherpunks.ru/nncp/v8/yggdrasil"
"golang.org/x/net/netutil"
)
close(nodeIdC)
}
+func startMCDTx(ctx *nncp.Ctx, port int, zeroInterval bool) error {
+ ifis, err := net.Interfaces()
+ if err != nil {
+ return err
+ }
+ for ifiReString, secs := range ctx.MCDTxIfis {
+ ifiRe, err := regexp.CompilePOSIX(ifiReString)
+ if err != nil {
+ return err
+ }
+ var interval time.Duration
+ if !zeroInterval {
+ interval = time.Duration(secs) * time.Second
+ }
+ for _, ifi := range ifis {
+ if ifiRe.MatchString(ifi.Name) {
+ if err = ctx.MCDTx(ifi.Name, port, interval); err != nil {
+ return err
+ }
+ }
+ }
+ }
+ return nil
+}
+
func main() {
var (
cfgPath = flag.String("cfg", nncp.DefaultCfgPath, "Path to configuration file")
bind = flag.String("bind", "[::]:5400", "Address to bind to")
ucspi = flag.Bool("ucspi", false, "Is it started as UCSPI-TCP server")
inetd = flag.Bool("inetd", false, "Obsolete, use -ucspi")
- yggdrasil = flag.String("yggdrasil", "", "Start Yggdrasil listener: PRV;BIND[,...];[PUB,...];[PEER,...]")
+ yggdrasil = flag.String("yggdrasil", "", "Start Yggdrasil listener: yggdrasils://PRV[:PORT]?[bind=BIND][&pub=PUB][&peer=PEER][&mcast=REGEX[:PORT]]")
maxConn = flag.Int("maxconn", 128, "Maximal number of simultaneous connections")
noCK = flag.Bool("nock", false, "Do no checksum checking")
mcdOnce = flag.Bool("mcd-once", false, "Send MCDs once and quit")
return
}
- var ln net.Listener
- if *yggdrasil != "" {
- ln, err = nncp.NewYggdrasilListener(ctx.YggdrasilAliases, *yggdrasil)
- if err != nil {
- log.Fatalln("Can not listen:", err)
- }
- } else {
+ conns := make(chan net.Conn)
+ if *bind != "" {
cols := strings.Split(*bind, ":")
port, err := strconv.Atoi(cols[len(cols)-1])
if err != nil {
}
if *mcdOnce {
- for ifiName := range ctx.MCDTxIfis {
- if err = ctx.MCDTx(ifiName, port, 0); err != nil {
- log.Fatalln("Can not do MCD transmission:", err)
- }
+ if err = startMCDTx(ctx, port, true); err != nil {
+ log.Fatalln("Can not do MCD transmission:", err)
}
return
}
- ln, err = net.Listen("tcp", *bind)
+ ln, err := net.Listen("tcp", *bind)
if err != nil {
log.Fatalln("Can not listen:", err)
}
-
- for ifiName, secs := range ctx.MCDTxIfis {
- if err = ctx.MCDTx(ifiName, port, time.Duration(secs)*time.Second); err != nil {
- log.Fatalln("Can not run MCD transmission:", err)
- }
+ if err = startMCDTx(ctx, port, false); err != nil {
+ log.Fatalln("Can not do MCD transmission:", err)
}
+ ln = netutil.LimitListener(ln, *maxConn)
+ go func() {
+ for {
+ conn, err := ln.Accept()
+ if err != nil {
+ log.Fatalln("Can not accept connection on TCP:", err)
+ }
+ conns <- conn
+ }
+ }()
}
- ln = netutil.LimitListener(ln, *maxConn)
- for {
- conn, err := ln.Accept()
+ if *yggdrasil != "" {
+ ln, err := nncpYggdrasil.NewListener(ctx.YggdrasilAliases, *yggdrasil)
if err != nil {
- log.Fatalln("Can not accept connection:", err)
+ log.Fatalln("Can not listen:", err)
}
+ ln = netutil.LimitListener(ln, *maxConn)
+ go func() {
+ for {
+ conn, err := ln.Accept()
+ if err != nil {
+ log.Fatalln("Can not accept connection on Yggdrasil:", err)
+ }
+ conns <- conn
+ }
+ }()
+ }
+
+ for conn := range conns {
ctx.LogD(
"daemon-accepted",
nncp.LEs{{K: "Addr", V: conn.RemoteAddr()}},
}
conn.Close()
}(conn)
+
}
}