// mainLoop initiates all ports and handles the traffic func mainLoop() { openPorts() defer closePorts() // Connections monitoring routine waitCh := make(chan bool) go func() { for { v := <-inCh if v && waitCh != nil { waitCh <- true } if !v { log.Println("IN port is closed. Interrupting execution") exitCh <- syscall.SIGTERM break } } }() log.Println("Waiting for port connections to establish... ") select { case <-waitCh: log.Println("Input port connected") waitCh = nil case <-time.Tick(30 * time.Second): log.Println("Timeout: port connections were not established within provided interval") exitCh <- syscall.SIGTERM return } log.Println("Started...") for { ip, err := inPort.RecvMessageBytes(0) if err != nil { continue } if !runtime.IsValidIP(ip) { continue } switch { case runtime.IsPacket(ip): fmt.Println("IP:", string(ip[1])) case runtime.IsOpenBracket(ip): fmt.Println("[") case runtime.IsCloseBracket(ip): fmt.Println("]") } } }
// mainLoop initiates all ports and handles the traffic func mainLoop() { service := NewService() openPorts() defer closePorts() go func() { outPort, err = utils.CreateOutputPort("tcp/server.out", *outputEndpoint, outCh) utils.AssertError(err) for data := range service.Output { outPort.SendMessage(runtime.NewOpenBracket()) outPort.SendMessage(runtime.NewPacket(data[0])) outPort.SendMessage(runtime.NewPacket(data[1])) outPort.SendMessage(runtime.NewCloseBracket()) } }() waitCh := make(chan bool) go func() { total := 0 for { select { case v := <-inCh: if !v { log.Println("IN port is closed. Interrupting execution") exitCh <- syscall.SIGTERM break } else { total++ } case v := <-outCh: if !v { log.Println("OUT port is closed. Interrupting execution") exitCh <- syscall.SIGTERM break } else { total++ } } if total >= 2 && waitCh != nil { waitCh <- true } } }() log.Println("Waiting for port connections to establish... ") select { case <-waitCh: log.Println("Ports connected") waitCh = nil case <-time.Tick(30 * time.Second): log.Println("Timeout: port connections were not established within provided interval") exitCh <- syscall.SIGTERM return } // Wait for the configuration on the options port log.Println("Waiting for configuration...") var bindAddr string for { ip, err := optionsPort.RecvMessageBytes(0) if err != nil { log.Println("Error receiving IP:", err.Error()) continue } if !runtime.IsValidIP(ip) || !runtime.IsPacket(ip) { continue } bindAddr = string(ip[1]) break } optionsPort.Close() // Create binding address listener laddr, err := net.ResolveTCPAddr("tcp", bindAddr) if err != nil { log.Fatalln(err) } listener, err := net.ListenTCP("tcp", laddr) if err != nil { log.Fatalln(err) } log.Println("Listening on", listener.Addr()) go service.Serve(listener) log.Println("Started...") var ( connID string data []byte ) for { ip, err := inPort.RecvMessageBytes(0) if err != nil { log.Println("Error receiving message:", err.Error()) continue } if !runtime.IsValidIP(ip) { continue } switch { case runtime.IsOpenBracket(ip): connID = "" data = nil case runtime.IsPacket(ip): if connID == "" { connID = string(ip[1]) } else { data = ip[1] } case runtime.IsCloseBracket(ip): service.Dispatch(connID, data) } } }