package main import ( "bytes" "crypto/rand" "encoding/json" "fmt" "io/ioutil" "log" "net/http" "sync" "time" libp2p "github.com/libp2p/go-libp2p" crypto "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/peer" ) var ( authCode string peers []string authMutex sync.Mutex authenticated = make(map[string]bool) hostID peer.ID ) type Message struct { ID string `json:"id"` Type string `json:"type"` Content string `json:"content"` } type CrawlerConfig struct { ID string Host string Port int AuthCode string } func loadNodeConfig() { config := loadConfig() authCode = config.AuthCode peers = config.Peers } func initP2P() (peer.ID, error) { priv, _, err := crypto.GenerateKeyPairWithReader(crypto.Ed25519, 2048, rand.Reader) if err != nil { return "", fmt.Errorf("failed to generate key pair: %v", err) } h, err := libp2p.New(libp2p.Identity(priv)) if err != nil { return "", fmt.Errorf("failed to create libp2p host: %v", err) } return h.ID(), nil } func sendMessage(serverAddr string, msg Message) error { msgBytes, err := json.Marshal(msg) if err != nil { return fmt.Errorf("failed to marshal message: %v", err) } req, err := http.NewRequest("POST", serverAddr, bytes.NewBuffer(msgBytes)) if err != nil { return fmt.Errorf("failed to create request: %v", err) } req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", authCode) client := &http.Client{ Timeout: time.Second * 10, } resp, err := client.Do(req) if err != nil { return fmt.Errorf("failed to send request: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { body, _ := ioutil.ReadAll(resp.Body) return fmt.Errorf("server error: %s", body) } return nil } func handleNodeRequest(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) return } auth := r.Header.Get("Authorization") if auth != authCode { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } var msg Message err := json.NewDecoder(r.Body).Decode(&msg) if err != nil { http.Error(w, "Error parsing JSON", http.StatusBadRequest) return } defer r.Body.Close() log.Printf("Received message: %+v\n", msg) w.Write([]byte("Message received")) interpretMessage(msg) } func startNodeClient() { for { for _, peerAddr := range peers { msg := Message{ ID: hostID.Pretty(), Type: "test", Content: "This is a test message from the client node", } err := sendMessage(peerAddr, msg) if err != nil { log.Printf("Error sending message to %s: %v", peerAddr, err) } else { log.Println("Message sent successfully to", peerAddr) } } time.Sleep(10 * time.Second) } } func interpretMessage(msg Message) { switch msg.Type { case "test": fmt.Println("Received test message:", msg.Content) case "update": fmt.Println("Received update message:", msg.Content) go update() case "heartbeat": handleHeartbeat(msg.Content) case "election": handleElection(msg.Content) default: fmt.Println("Received unknown message type:", msg.Type) } }