11package main
22
33import (
4+ "bufio"
45 "context"
6+ "encoding/json"
57 "fmt"
8+ "net"
69 "os"
710 "os/signal"
811 "runtime"
12+ "strings"
913 "syscall"
1014 "time"
1115
1216 core "github.com/monster0506/meshexec/internal"
1317 "github.com/monster0506/meshexec/internal/agent"
1418 "github.com/monster0506/meshexec/internal/config"
19+ "github.com/monster0506/meshexec/internal/discovery"
1520 "github.com/monster0506/meshexec/internal/executor"
1621 "github.com/monster0506/meshexec/internal/mesh"
1722 "github.com/monster0506/meshexec/internal/targeting"
@@ -55,9 +60,15 @@ func runDaemon(cmd *cobra.Command) error {
5560 _ = os .Setenv ("MESHEXEC_BLE_IMPL" , "sidecar" )
5661 }
5762
63+ if logger != nil {
64+ logger .Info ("daemon: building mesh node" , nil )
65+ }
5866 // Build mesh node
5967 node , err := newMeshNodeForDaemon (cfg )
6068 if err != nil {
69+ if logger != nil {
70+ logger .Error ("daemon: mesh init failed" , err , nil )
71+ }
6172 return fmt .Errorf ("mesh init: %w" , err )
6273 }
6374
@@ -76,11 +87,20 @@ func runDaemon(cmd *cobra.Command) error {
7687 // Start services
7788 ctx , cancel := context .WithCancel (context .Background ())
7889 defer cancel ()
90+ if logger != nil {
91+ logger .Info ("daemon: starting node and agent" , nil )
92+ }
7993 if err := node .Start (ctx ); err != nil {
94+ if logger != nil {
95+ logger .Error ("daemon: mesh start failed" , err , nil )
96+ }
8097 return fmt .Errorf ("mesh start: %w" , err )
8198 }
8299 if err := ag .Start (ctx ); err != nil {
83100 _ = node .Stop ()
101+ if logger != nil {
102+ logger .Error ("daemon: agent start failed" , err , nil )
103+ }
84104 return fmt .Errorf ("agent start: %w" , err )
85105 }
86106
@@ -99,6 +119,103 @@ func runDaemon(cmd *cobra.Command) error {
99119 logger .Info ("daemon: received result" , map [string ]interface {}{"id" : m .ID , "from" : m .Sender , "ttl" : m .TTL })
100120 }
101121 }()
122+ // Start simple TCP listener for POC/discovery port and mDNS advertise
123+ go func (port int ) {
124+ addr := fmt .Sprintf (":%d" , port )
125+ if logger != nil {
126+ logger .Info ("daemon: starting tcp listener" , map [string ]interface {}{"addr" : addr })
127+ }
128+ ln , err := net .Listen ("tcp" , addr )
129+ if err != nil {
130+ if logger != nil {
131+ logger .Warn ("tcp listen failed" , map [string ]interface {}{"addr" : addr , "error" : err .Error ()})
132+ }
133+ return
134+ }
135+ if logger != nil {
136+ logger .Info ("daemon: tcp listener ready" , map [string ]interface {}{"addr" : addr })
137+ }
138+ // mDNS advertise
139+ adv , err := discovery .StartAdvertiser (cfg .Device .Name , port , map [string ]string {
140+ "role" : cfg .Device .Role ,
141+ "os" : cfg .Device .OS ,
142+ "arch" : cfg .Device .Arch ,
143+ })
144+ if err == nil {
145+ if logger != nil {
146+ logger .Info ("daemon: mdns advertiser started" , map [string ]interface {}{"name" : cfg .Device .Name , "port" : port })
147+ }
148+ go func () { <- ctx .Done (); adv .Stop () }()
149+ }
150+ go func () { <- ctx .Done (); _ = ln .Close () }()
151+ for {
152+ c , err := ln .Accept ()
153+ if err != nil {
154+ select {
155+ case <- ctx .Done ():
156+ return
157+ default :
158+ }
159+ if logger != nil {
160+ logger .Warn ("daemon: accept error" , map [string ]interface {}{"error" : err .Error ()})
161+ }
162+ continue
163+ }
164+ go func (conn net.Conn ) {
165+ if logger != nil {
166+ logger .Info ("daemon: connection accepted" , map [string ]interface {}{"remote" : conn .RemoteAddr ().String ()})
167+ }
168+ defer func () { _ = conn .Close () }()
169+ // Read one line; support raw text or JSON {"cmd":"..."}
170+ r := bufio .NewReader (conn )
171+ line , _ := r .ReadString ('\n' )
172+ if logger != nil {
173+ logger .Debug ("daemon: received line" , map [string ]interface {}{"bytes" : len (line )})
174+ }
175+ cmdStr := ""
176+ var payload struct {
177+ Cmd string `json:"cmd"`
178+ }
179+ if json .Unmarshal ([]byte (line ), & payload ) == nil && payload .Cmd != "" {
180+ cmdStr = payload .Cmd
181+ } else {
182+ cmdStr = line
183+ }
184+ cmdStr = strings .TrimSpace (cmdStr )
185+ if cmdStr == "" {
186+ return
187+ }
188+ if logger != nil {
189+ logger .Info ("daemon: executing" , map [string ]interface {}{"cmd" : cmdStr })
190+ }
191+ // Execute command via executor
192+ ctxExec , cancel := context .WithTimeout (context .Background (), 30 * time .Second )
193+ defer cancel ()
194+ res , err := exec .Execute (ctxExec , cmdStr )
195+ if err != nil && res != nil && res .Stderr == "" {
196+ res .Stderr = err .Error ()
197+ }
198+ if res != nil && logger != nil {
199+ logger .Debug ("daemon: exec result" , map [string ]interface {}{"code" : res .ExitCode , "stdout_len" : len (res .Stdout ), "stderr_len" : len (res .Stderr )})
200+ }
201+ if res != nil {
202+ if res .ExitCode == 0 && res .Status == "" {
203+ res .Status = "success"
204+ }
205+ if res .ExitCode != 0 && res .Status == "" {
206+ res .Status = "failed"
207+ }
208+ }
209+ _ = json .NewEncoder (conn ).Encode (map [string ]interface {}{
210+ "ok" : true ,
211+ "result" : res ,
212+ })
213+ if logger != nil {
214+ logger .Info ("daemon: response sent" , map [string ]interface {}{"remote" : conn .RemoteAddr ().String ()})
215+ }
216+ }(c )
217+ }
218+ }(cfg .Network .TCPPort )
102219 }
103220
104221 // Wait for termination signal (test seam)
0 commit comments