Skip to content

Commit

Permalink
server: Add bound addresses IPC events
Browse files Browse the repository at this point in the history
This adds a new set of IPC events sent over the TX pipe that report the
locally bound addresses of the P2P and RPC interfaces.

The main goal for this feature is to enable binding dcrd to a random
port (using for example, --listen :0) while enabling a controlling
parent process to learn the address that was assigned to dcrd by the OS.

The events are only sent when the --boundaddrevents flag is specified.
  • Loading branch information
matheusd authored and davecgh committed Nov 23, 2022
1 parent e9b1b58 commit fc017ce
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 3 deletions.
7 changes: 4 additions & 3 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,10 @@ type config struct {
DropExistsAddrIndex bool `long:"dropexistsaddrindex" description:"Deletes the exists address index from the database on start up and then exits"`

// IPC options.
PipeRx uint `long:"piperx" description:"File descriptor of read end pipe to enable parent -> child process communication"`
PipeTx uint `long:"pipetx" description:"File descriptor of write end pipe to enable parent <- child process communication"`
LifetimeEvents bool `long:"lifetimeevents" description:"Send lifetime notifications over the TX pipe"`
PipeRx uint `long:"piperx" description:"File descriptor of read end pipe to enable parent -> child process communication"`
PipeTx uint `long:"pipetx" description:"File descriptor of write end pipe to enable parent <- child process communication"`
LifetimeEvents bool `long:"lifetimeevents" description:"Send lifetime notifications over the TX pipe"`
BoundAddrEvents bool `long:"boundaddrevents" description:"Send notifications with the locally bound addresses of the P2P and RPC subsystems over the TX pipe"`

// Cooked options ready for use.
onionlookup func(string) ([]net.IP, error)
Expand Down
56 changes: 56 additions & 0 deletions ipc.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,59 @@ func (s lifetimeEventServer) notifyShutdownEvent(action lifetimeAction) {
action: action,
}
}

// boundP2PListenAddrEvent are IPC events emitted by dcrd with the bound local
// addresses for the P2P interface. Multiple events of this type may be
// generated.
//
// The type of this event is "p2plistenaddr" and the payload is the UTF-8
// encoded address.
type boundP2PListenAddrEvent string

func (e boundP2PListenAddrEvent) Type() string { return "p2plistenaddr" }
func (e boundP2PListenAddrEvent) PayloadSize() uint32 { return uint32(len(e)) }
func (e boundP2PListenAddrEvent) WritePayload(w io.Writer) error {
_, err := w.Write([]byte(e))
return err
}

// boundRPCListenAddrEvent are IPC events emitted by dcrd with the bound local
// addresses for the RPC interface. Multiple events of this type may be
// generated.
//
// The type of this event is "rpclistenaddr" and the payload is the UTF-8
// encoded address.
type boundRPCListenAddrEvent string

func (e boundRPCListenAddrEvent) Type() string { return "rpclistenaddr" }
func (e boundRPCListenAddrEvent) PayloadSize() uint32 { return uint32(len(e)) }
func (e boundRPCListenAddrEvent) WritePayload(w io.Writer) error {
_, err := w.Write([]byte(e))
return err
}

// boundAddrEventServer is a server that can notify parent processes, via the
// IPC mechanism, the local addresses to which specific subsystems are bound
// during initialization.
//
// The empty value is a valid server and will not send any events if its
// notify* methods are called.
type boundAddrEventServer chan<- pipeMessage

func newBoundAddrEventServer(outChan chan<- pipeMessage) boundAddrEventServer {
return boundAddrEventServer(outChan)
}

func (s boundAddrEventServer) notifyP2PAddress(addr string) {
if s == nil {
return
}
s <- boundP2PListenAddrEvent(addr)
}

func (s boundAddrEventServer) notifyRPCAddress(addr string) {
if s == nil {
return
}
s <- boundRPCListenAddrEvent(addr)
}
12 changes: 12 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3277,6 +3277,11 @@ func genCertPair(certFile, keyFile string, altDNSNames []string, tlsCurve ellipt
// with the RPC server depending on the configuration settings for listen
// addresses and TLS.
func setupRPCListeners() ([]net.Listener, error) {
var notifyAddrServer boundAddrEventServer
if cfg.BoundAddrEvents {
notifyAddrServer = newBoundAddrEventServer(outgoingPipeMessages)
}

// Setup TLS if not disabled.
listenFunc := net.Listen
if !cfg.DisableRPC && !cfg.DisableTLS {
Expand Down Expand Up @@ -3342,6 +3347,7 @@ func setupRPCListeners() ([]net.Listener, error) {
continue
}
listeners = append(listeners, listener)
notifyAddrServer.notifyRPCAddress(listener.Addr().String())
}

return listeners, nil
Expand Down Expand Up @@ -3833,6 +3839,11 @@ func initListeners(ctx context.Context, params *chaincfg.Params, amgr *addrmgr.A
return nil, nil, err
}

var notifyAddrServer boundAddrEventServer
if cfg.BoundAddrEvents {
notifyAddrServer = newBoundAddrEventServer(outgoingPipeMessages)
}

listeners := make([]net.Listener, 0, len(netAddrs))
for _, addr := range netAddrs {
var listenConfig net.ListenConfig
Expand All @@ -3842,6 +3853,7 @@ func initListeners(ctx context.Context, params *chaincfg.Params, amgr *addrmgr.A
continue
}
listeners = append(listeners, listener)
notifyAddrServer.notifyP2PAddress(listener.Addr().String())
}

var nat *upnpNAT
Expand Down

0 comments on commit fc017ce

Please sign in to comment.