Beispiel #1
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	inPort, err = utils.CreateInputPort("debug/crasher.in", *inputEndpoint, inCh)
	utils.AssertError(err)

	outPort, err = utils.CreateOutputPort("debug/crasher.out", *outputEndpoint, outCh)
	utils.AssertError(err)
}
Beispiel #2
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	intervalPort, err = utils.CreateInputPort("ticker.interval", *intervalEndpoint, nil)
	utils.AssertError(err)

	outPort, err = utils.CreateOutputPort("ticker.out", *outputEndpoint, outCh)
	utils.AssertError(err)
}
Beispiel #3
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	inPort, err = utils.CreateInputPort("", *inputEndpoint, nil)
	utils.AssertError(err)

	outPort, err = utils.CreateOutputPort("bonjour/discover.out", *outputEndpoint, outCh)
	utils.AssertError(err)
}
Beispiel #4
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	inPort, err = utils.CreateInputPort("passthru.in", *inputEndpoint, inCh)
	utils.AssertError(err)

	outPort, err = utils.CreateOutputPort("passthru.out", *outputEndpoint, outCh)
	utils.AssertError(err)
}
Beispiel #5
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	optionsPort, err = utils.CreateInputPort("tcp/server.options", *optionsEndpoint, nil)
	utils.AssertError(err)

	inPort, err = utils.CreateInputPort("tcp/server.in", *inputEndpoint, inCh)
	utils.AssertError(err)
}
Beispiel #6
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	inPort, err = utils.CreateInputPort("fs/watchdog.in", *inputEndpoint, nil)
	utils.AssertError(err)

	if *errorEndpoint != "" {
		errPort, err = utils.CreateOutputPort("fs/watchdog.err", *errorEndpoint, errCh)
		utils.AssertError(err)
	}
}
Beispiel #7
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	optionsPort, err = utils.CreateInputPort("distinct.options", *optionsEndpoint, nil)
	utils.AssertError(err)

	inPort, err = utils.CreateInputPort("distinct.in", *inputEndpoint, inCh)
	utils.AssertError(err)

	outPort, err = utils.CreateOutputPort("distinct.out", *outputEndpoint, outCh)
	utils.AssertError(err)
}
Beispiel #8
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	delayPort, err = utils.CreateInputPort("delay.delay", *delayEndpoint, nil)
	utils.AssertError(err)

	inPort, err = utils.CreateInputPort("delay.in", *inputEndpoint, inCh)
	utils.AssertError(err)

	outPort, err = utils.CreateOutputPort("delay.out", *outputEndpoint, outCh)
	utils.AssertError(err)
}
Beispiel #9
0
func openPorts() {
	context, err = zmq.NewContext()
	utils.AssertError(err)

	optionsPort, err = utils.CreateInputPort(context, *optionsEndpoint)
	utils.AssertError(err)

	inPort, err = utils.CreateInputPort(context, *inputEndpoint)
	utils.AssertError(err)
}
Beispiel #10
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	patternPort, err = utils.CreateInputPort("submatch.pattern", *patternEndpoint, nil)
	utils.AssertError(err)

	inPort, err = utils.CreateInputPort("submatch.in", *inputEndpoint, inCh)
	utils.AssertError(err)

	mapPort, err = utils.CreateOutputPort("submatch.map", *mapEndpoint, mapCh)
	utils.AssertError(err)
}
Beispiel #11
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	tplPort, err = utils.CreateInputPort("template.tpl", *tplEndpoint, nil)
	utils.AssertError(err)

	inPort, err = utils.CreateInputPort("template.in", *inputEndpoint, inCh)
	utils.AssertError(err)

	outPort, err = utils.CreateOutputPort("template.out", *outputEndpoint, outCh)
	utils.AssertError(err)
}
Beispiel #12
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	filePort, err = utils.CreateInputPort("readfile.file", *fileEndpoint, fileCh)
	utils.AssertError(err)

	outPort, err = utils.CreateOutputPort("readfile.out", *outputEndpoint, outCh)
	utils.AssertError(err)

	if *errorEndpoint != "" {
		errPort, err = utils.CreateOutputPort("readfile.err", *errorEndpoint, errCh)
		utils.AssertError(err)
	}
}
Beispiel #13
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	inPort, err = utils.CreateInputPort("fs/walk.dir", *inputEndpoint, inCh)
	utils.AssertError(err)

	outPort, err = utils.CreateOutputPort("fs/walk.file", *outputEndpoint, outCh)
	utils.AssertError(err)

	if *errorEndpoint != "" {
		errPort, err = utils.CreateOutputPort("fs/walk.err", *errorEndpoint, errCh)
		utils.AssertError(err)
	}
}
Beispiel #14
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	optionsPort, err = utils.CreateInputPort("influxdb/write.options", *optionsEndpoint, nil)
	utils.AssertError(err)

	inPort, err = utils.CreateInputPort("influxdb/write.in", *inputEndpoint, inCh)
	utils.AssertError(err)

	if *errorEndpoint != "" {
		errPort, err = utils.CreateOutputPort("influxdb/write.err", *errorEndpoint, errCh)
		utils.AssertError(err)
	}
}
Beispiel #15
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	cmdPort, err = utils.CreateInputPort("exec.cmd", *cmdEndpoint, cmdCh)
	utils.AssertError(err)

	if *outputEndpoint != "" {
		outPort, err = utils.CreateOutputPort("exec.out", *outputEndpoint, outCh)
		utils.AssertError(err)
	}

	if *errorEndpoint != "" {
		errPort, err = utils.CreateOutputPort("exec.err", *errorEndpoint, errCh)
		utils.AssertError(err)
	}
}
Beispiel #16
0
func openPorts() {
	optsPort, err = utils.CreateInputPort("mqtt-property.options", *optionsEndpoint, nil)
	utils.AssertError(err)

	tmplPort, err = utils.CreateInputPort("mqtt-property.template", *templateEndpoint, nil)
	utils.AssertError(err)

	propPort, err = utils.CreateOutputPort("mqtt-property.property", *propertyEndpoint, outCh)
	utils.AssertError(err)

	if *errorEndpoint != "" {
		errPort, err = utils.CreateOutputPort("mqtt-property.err", *errorEndpoint, nil)
		utils.AssertError(err)
	}
}
Beispiel #17
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	reqPort, err = utils.CreateInputPort("http/client.req", *requestEndpoint, reqCh)
	utils.AssertError(err)

	if *responseEndpoint != "" {
		respPort, err = utils.CreateOutputPort("http/client.resp", *responseEndpoint, respCh)
		utils.AssertError(err)
	}
	if *bodyEndpoint != "" {
		bodyPort, err = utils.CreateOutputPort("http/client.body", *bodyEndpoint, bodyCh)
		utils.AssertError(err)
	}
	if *errorEndpoint != "" {
		errPort, err = utils.CreateOutputPort("http/client.err", *errorEndpoint, errCh)
		utils.AssertError(err)
	}
}
Beispiel #18
0
func openPorts() {
	requestPort, err = utils.CreateInputPort(*requestEndpoint)
	utils.AssertError(err)

	failPort, err = utils.CreateOutputPort(*failEndpoint)
	utils.AssertError(err)

	successes := strings.Split(*successEndpoint, ",")
	successPorts = make(map[string]*zmq.Socket, len(successes))

	var port *zmq.Socket

	for i, endpoint := range patterns {
		port, err = utils.CreateOutputPort(strings.TrimSpace(successes[i]))
		utils.AssertError(err)
		successPorts
	}
}
Beispiel #19
0
func openPorts() {
	// Data
	dataports := strings.Split(*dataEndpoint, ",")
	if len(dataports) == 0 {
		flag.Usage()
		os.Exit(1)
	}

	dataPortsArray = []*zmq.Socket{}
	poller = zmq.NewPoller()

	for i, endpoint := range dataports {
		endpoint = strings.TrimSpace(endpoint)
		log.Printf("Connecting DATA[%v]=%s", i, endpoint)
		port, err := utils.CreateInputPort(fmt.Sprintf("context.data-%s", i), endpoint, inCh)
		utils.AssertError(err)

		dataPortsArray = append(dataPortsArray, port)
		poller.Add(port, zmq.POLLIN)
	}

	// Template
	tmplPort, err = utils.CreateInputPort("context.tmpl", *templateEndpoint, nil)
	utils.AssertError(err)

	// Update
	if *updatedEndpoint != "" {
		updPort, err = utils.CreateOutputPort("context.update", *updatedEndpoint, outCh)
		utils.AssertError(err)
	}

	// Match
	if *matchedEndpoint != "" {
		matchPort, err = utils.CreateOutputPort("context.match", *matchedEndpoint, outCh)
		utils.AssertError(err)
	}

	// Error
	if *errorEndpoint != "" {
		errPort, err = utils.CreateOutputPort("context.err", *errorEndpoint, nil)
		utils.AssertError(err)
	}
}
Beispiel #20
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	inports := strings.Split(*inputEndpoint, ",")
	if len(inports) == 0 {
		flag.Usage()
		exitCh <- syscall.SIGTERM
		return
	}

	inPortArray = []*zmq.Socket{}
	poller = zmq.NewPoller()

	for i, endpoint := range inports {
		endpoint = strings.TrimSpace(endpoint)
		log.Printf("Binding IN[%v]=%s", i, endpoint)
		port, err = utils.CreateInputPort(fmt.Sprintf("joiner.in[%v]", i), endpoint, inCh)
		utils.AssertError(err)
		inPortArray = append(inPortArray, port)
		poller.Add(port, zmq.POLLIN)
	}

	outPort, err = utils.CreateOutputPort("joiner.out", *outputEndpoint, outCh)
	utils.AssertError(err)
}
Beispiel #21
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	outports := strings.Split(*outputEndpoint, ",")
	if len(outports) == 0 {
		flag.Usage()
		os.Exit(1)
	}

	inPort, err = utils.CreateInputPort("splitter.in", *inputEndpoint, inCh)
	utils.AssertError(err)

	outPortArray = []*zmq.Socket{}
	for i, endpoint := range outports {
		endpoint = strings.TrimSpace(endpoint)
		log.Printf("Connecting OUT[%v]=%s", i, endpoint)
		port, err = utils.CreateOutputPort(fmt.Sprintf("splitter.out[%v]", i), endpoint, outCh)
		outPortArray = append(outPortArray, port)
	}
}
Beispiel #22
0
func openPorts() {
	var err error

	// Input sockets
	// Interval socket
	intPort, err = utils.CreateInputPort("http-property.int", *intervalEndpoint, nil)
	utils.AssertError(err)

	// Request socket
	reqPort, err = utils.CreateInputPort("http-property.req", *requestEndpoint, nil)
	utils.AssertError(err)

	// Property template socket
	tmplPort, err = utils.CreateInputPort("http-property.tmpl", *templateEndpoint, nil)
	utils.AssertError(err)

	// Output sockets
	// Property socket
	if *propertyEndpoint != "" {
		propPort, err = utils.CreateOutputPort("http-property.prop", *propertyEndpoint, outCh)
		utils.AssertError(err)
	}

	// Response socket
	if *responseEndpoint != "" {
		respPort, err = utils.CreateOutputPort("http-property.resp", *responseEndpoint, outCh)
		utils.AssertError(err)
	}

	// Response body socket
	if *bodyEndpoint != "" {
		bodyPort, err = utils.CreateOutputPort("http-property.body", *bodyEndpoint, outCh)
		utils.AssertError(err)
	}

	// Error socket
	if *errorEndpoint != "" {
		errPort, err = utils.CreateOutputPort("http-property.err", *errorEndpoint, outCh)
		utils.AssertError(err)

	}
}
Beispiel #23
0
// 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)
		}
	}
}
Beispiel #24
0
// mainLoop initiates all ports and handles the traffic
func mainLoop() {
	openPorts()
	defer closePorts()

	ports := 1
	if bodyPort != nil {
		ports++
	}
	if respPort != nil {
		ports++
	}
	if errPort != nil {
		ports++
	}

	waitCh := make(chan bool)
	reqExitCh := make(chan bool, 1)
	go func(num int) {
		total := 0
		for {
			select {
			case v := <-reqCh:
				if v {
					total++
				} else {
					reqExitCh <- true
				}
			case v := <-bodyCh:
				if !v {
					log.Println("BODY port is closed. Interrupting execution")
					exitCh <- syscall.SIGTERM
					break
				} else {
					total++
				}
			case v := <-respCh:
				if !v {
					log.Println("RESP port is closed. Interrupting execution")
					exitCh <- syscall.SIGTERM
					break
				} else {
					total++
				}
			case v := <-errCh:
				if !v {
					log.Println("ERR port is closed. Interrupting execution")
					exitCh <- syscall.SIGTERM
					break
				} else {
					total++
				}
			}
			if total >= num && waitCh != nil {
				waitCh <- true
			}
		}
	}(ports)

	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
	}

	// This is obviously dangerous but we need it to deal with our custom CA's
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	client.Timeout = 30 * time.Second

	// Main loop
	var (
		ip            [][]byte
		clientOptions *httputils.HTTPClientOptions
		request       *http.Request
	)

	log.Println("Started")

	for {
		ip, err = reqPort.RecvMessageBytes(zmq.DONTWAIT)
		if err != nil {
			select {
			case <-reqExitCh:
				log.Println("REQ port is closed. Interrupting execution")
				exitCh <- syscall.SIGTERM
				break
			default:
				// IN port is still open
			}
			time.Sleep(2 * time.Second)
			continue
		}
		if !runtime.IsValidIP(ip) {
			log.Println("Invalid IP:", ip)
			continue
		}

		err = json.Unmarshal(ip[1], &clientOptions)
		if err != nil {
			log.Println("ERROR: failed to unmarshal request options:", err.Error())
			continue
		}
		if clientOptions == nil {
			log.Println("ERROR: received nil request options")
			continue
		}

		if clientOptions.Form != nil {
			request, err = http.NewRequest(clientOptions.Method, clientOptions.URL, strings.NewReader(clientOptions.Form.Encode()))
		} else {
			request, err = http.NewRequest(clientOptions.Method, clientOptions.URL, nil)
		}
		utils.AssertError(err)

		if clientOptions.ContentType != "" {
			request.Header.Add("Content-Type", clientOptions.ContentType)
		}

		for k, v := range clientOptions.Headers {
			request.Header.Add(k, v[0])
		}

		response, err := client.Do(request)
		if err != nil {
			log.Printf("ERROR performing HTTP %s %s: %s", request.Method, request.URL, err.Error())
			if errPort != nil {
				errPort.SendMessageDontwait(runtime.NewPacket([]byte(err.Error())))
			}
			clientOptions = nil
			continue
		}
		resp, err := httputils.Response2Response(response)
		if err != nil {
			log.Printf("ERROR converting response to reply: %s", err.Error())
			if errPort != nil {
				errPort.SendMessageDontwait(runtime.NewPacket([]byte(err.Error())))
			}
			clientOptions = nil
			continue
		}
		ip, err = httputils.Response2IP(resp)
		if err != nil {
			log.Printf("ERROR converting reply to IP: %s", err.Error())
			if errPort != nil {
				errPort.SendMessageDontwait(runtime.NewPacket([]byte(err.Error())))
			}
			clientOptions = nil
			continue
		}

		if respPort != nil {
			respPort.SendMessage(ip)
		}
		if bodyPort != nil {
			bodyPort.SendMessage(runtime.NewPacket(resp.Body))
		}

		select {
		case <-reqCh:
			log.Println("REQ port is closed. Interrupting execution")
			exitCh <- syscall.SIGTERM
			break
		default:
			// file port is still open
		}

		clientOptions = nil
		continue
	}
}
Beispiel #25
0
// mainLoop initiates all ports and handles the traffic
func mainLoop() {
	openPorts()
	defer closePorts()

	waitCh := make(chan bool)
	go func() {
		for {
			v := <-outCh
			if v && waitCh != nil {
				waitCh <- true
			}
			if !v {
				log.Println("OUT port is closed. Interrupting execution")
				exitCh <- syscall.SIGTERM
				break
			}
		}
	}()

	log.Println("Waiting for port connections to establish... ")
	select {
	case <-waitCh:
		log.Println("Output 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("Waiting for configuration IP...")
	var options *bonjour.ServiceRecord
	for {
		ip, err := inPort.RecvMessageBytes(0)
		if err != nil {
			continue
		}
		if !runtime.IsValidIP(ip) || !runtime.IsPacket(ip) {
			continue
		}
		if err = json.Unmarshal(ip[1], &options); err != nil {
			log.Println("Error decoding options:", err.Error())
			continue
		}
		inPort.Close()
		break
	}

	resolver, err = bonjour.NewResolver(nil)
	utils.AssertError(err)

	entries := make(chan *bonjour.ServiceEntry)
	err = resolver.Browse(options.Service, options.Domain, entries)
	utils.AssertError(err)

	log.Println("Started...")
	for e := range entries {
		data, err := json.Marshal(e)
		if err != nil {
			log.Println("Error encoding entry:", err.Error())
			continue
		}
		outPort.SendMessage(runtime.NewPacket(data))
	}

}
Beispiel #26
0
// mainLoop initiates all ports and handles the traffic
func mainLoop() {
	openPorts()
	defer closePorts()

	// Receiver routine
	go func() {
		inPort, err = utils.CreateInputPort("websocket/server.in", *inputEndpoint, inCh)
		utils.AssertError(err)
		defer inPort.Close()
		for {
			ip, err := inPort.RecvMessageBytes(0)
			if err != nil {
				continue
			}
			if !runtime.IsValidIP(ip) {
				continue
			}
			msg, err := wsutils.IP2Message(ip)
			if err != nil {
				log.Println("Failed to convert IP to Message:", err.Error())
				continue
			}
			log.Printf("Received response: %#v\n", msg)
			DefaultHub.Outgoing <- *msg
		}
	}()

	// Sender routine
	go func() {
		outPort, err = utils.CreateOutputPort("websocket/server.out", *outputEndpoint, outCh)
		utils.AssertError(err)
		defer outPort.Close()
		for msg := range DefaultHub.Incoming {
			log.Printf("Received data from connection: %#v\n", msg)
			ip, err := wsutils.Message2IP(&msg)
			if err != nil {
				log.Println("Failed to convert Message to IP:", err.Error())
				continue
			}
			outPort.SendMessageDontwait(ip)
		}
	}()

	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
	}

	log.Println("Waiting for configuration...")
	var bindAddr string
	for {
		ip, err := optionsPort.RecvMessageBytes(0)
		if err != nil {
			continue
		}
		if !runtime.IsValidIP(ip) || !runtime.IsPacket(ip) {
			continue
		}
		bindAddr = string(ip[1])
		break
	}
	optionsPort.Close()

	// Configure & start websocket server
	http.Handle("/", websocket.Handler(WebHandler))
	go DefaultHub.Start()

	// Listen & serve
	log.Printf("Listening %v", bindAddr)
	log.Printf("Web-socket endpoint: ws://%s/", bindAddr)
	if err := http.ListenAndServe(bindAddr, nil); err != nil {
		log.Fatal("ListenAndServe Error:", err)
	}
}
Beispiel #27
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	inPort, err = utils.CreateInputPort("drop.in", *inputEndpoint, inCh)
	utils.AssertError(err)
}
Beispiel #28
0
func main() {
	flag.Parse()

	if *jsonFlag {
		doc, _ := registryEntry.JSON()
		fmt.Println(string(doc))
		os.Exit(0)
	}

	log.SetFlags(0)
	if *debug {
		log.SetOutput(os.Stdout)
	} else {
		log.SetOutput(ioutil.Discard)
	}

	validateArgs()

	openPorts()
	defer closePorts()

	exitCh := utils.HandleInterruption()

	// Wait for the configuration on the options port
	var bindAddr string
	for {
		log.Println("Waiting for configuration...")
		ip, err := optionsPort.RecvMultipart(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()

	// Data from http handler and data to http handler
	inCh := make(chan httputils.HTTPResponse)
	outCh := make(chan HandlerRequest)

	go func(ctx *zmq.Context, endpoint string) {
		outPort, err = utils.CreateOutputPort(context, endpoint)
		utils.AssertError(err)

		// Map of uuid to requests
		dataMap := make(map[string]chan httputils.HTTPResponse)

		// Start listening in/out channels
		for {
			select {
			case data := <-outCh:
				dataMap[data.Request.Id] = data.ResponseCh
				ip, _ := httputils.Request2IP(data.Request)
				outPort.SendMultipart(ip, 0)
			case resp := <-inCh:
				if respCh, ok := dataMap[resp.Id]; ok {
					log.Println("Resolved channel for response", resp.Id)
					respCh <- resp
					delete(dataMap, resp.Id)
					continue
				}
				log.Println("Didn't find request handler mapping for a given ID", resp.Id)
			}
		}
	}(context, *outputEndpoint)

	// Web server goroutine
	go func() {
		mux := http.NewServeMux()
		mux.HandleFunc("/", Handler(outCh))

		s := &http.Server{
			Handler:        mux,
			ReadTimeout:    10 * time.Second,
			WriteTimeout:   10 * time.Second,
			MaxHeaderBytes: 1 << 20,
		}

		ln, err := net.Listen("tcp", bindAddr)
		if err != nil {
			log.Println(err.Error())
			exitCh <- syscall.SIGTERM
			return
		}

		log.Printf("Starting listening %v", bindAddr)
		err = s.Serve(ln)
		if err != nil {
			log.Println(err.Error())
			exitCh <- syscall.SIGTERM
			return
		}
	}()

	// Process incoming message forever
	for {
		ip, err := inPort.RecvMultipart(0)
		if err != nil {
			log.Println("Error receiving message:", err.Error())
			continue
		}
		if !runtime.IsValidIP(ip) {
			log.Println("Received invalid IP")
			continue
		}

		resp, err := httputils.IP2Response(ip)
		if err != nil {
			log.Printf("Error converting IP to response: %s", err.Error())
			continue
		}
		inCh <- *resp
	}
}
Beispiel #29
0
// openPorts create ZMQ sockets and start socket monitoring loops
func openPorts() {
	inPort, err = utils.CreateInputPort("bonjour/discover.options", *inputEndpoint, nil)
	utils.AssertError(err)
}
Beispiel #30
0
// mainLoop initiates all ports and handles the traffic
func mainLoop() {
	openPorts()
	defer closePorts()

	waitCh := make(chan bool)
	go func() {
		total := 0
		for {
			v := <-outCh
			if !v {
				log.Println("An OUT port is closed. Interrupting execution")
				exitCh <- syscall.SIGTERM
				break
			} else {
				total++
			}
			// At least one output ports are opened
			if total >= 1 && 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")
		os.Exit(1)
	}

	// Setup socket poll items
	poller := zmq.NewPoller()
	poller.Add(intPort, zmq.POLLIN)
	poller.Add(reqPort, zmq.POLLIN)
	poller.Add(tmplPort, zmq.POLLIN)

	// This is obviously dangerous but we need it to deal with our custom CA's
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	client.Timeout = 30 * time.Second

	var (
		interval     time.Duration
		ip           [][]byte
		request      *requestIP
		propTemplate *caf.PropertyTemplate
		httpRequest  *http.Request
	)

	for {
		sockets, err := poller.Poll(-1)
		if err != nil {
			log.Println("Error polling ports:", err.Error())
			continue
		}
		for _, socket := range sockets {
			if socket.Socket == nil {
				log.Println("ERROR: could not find socket in polling items array")
				continue
			}
			ip, err = socket.Socket.RecvMessageBytes(0)
			if err != nil {
				log.Println("Error receiving message:", err.Error())
				continue
			}
			if !runtime.IsValidIP(ip) || !runtime.IsPacket(ip) {
				log.Println("Invalid IP:", ip)
				continue
			}
			switch socket.Socket {
			case intPort:
				interval, err = time.ParseDuration(string(ip[1]))
				log.Println("Interval specified:", interval)
			case reqPort:
				err = json.Unmarshal(ip[1], &request)
				if err != nil {
					log.Println("ERROR: failed to unmarshal request:", err.Error())
					continue
				}
				log.Println("Request specified:", request)
			case tmplPort:
				err = json.Unmarshal(ip[1], &propTemplate)
				if err != nil {
					log.Println("ERROR: failed to unmarshal template:", err.Error())
					continue
				}
				log.Printf("Template specified: %+v", propTemplate)

			default:
				log.Println("ERROR: IP from unhandled socket received!")
				continue
			}
		}
		if interval > 0 && request != nil && propTemplate != nil {
			log.Println("Component configured. Moving on...")
			break
		}
	}

	log.Println("Started...")
	ticker := time.NewTicker(interval)
	for _ = range ticker.C {
		httpRequest, err = http.NewRequest(request.Method, request.URL, nil)
		utils.AssertError(err)

		// Set the accepted Content-Type
		if request.ContentType != "" {
			httpRequest.Header.Add("Content-Type", request.ContentType)
		}

		// Set any additional headers if provided
		for k, v := range request.Headers {
			httpRequest.Header.Add(k, v[0])
		}

		response, err := client.Do(httpRequest)
		if err != nil {
			log.Printf("ERROR performing HTTP %s %s: %s\n", request.Method, request.URL, err.Error())
			if errPort != nil {
				errPort.SendMessageDontwait(runtime.NewPacket([]byte(err.Error())))
			}
			continue
		}

		resp, err := httputils.Response2Response(response)
		if err != nil {
			log.Println("ERROR converting response to reply:", err.Error())
			if errPort != nil {
				errPort.SendMessageDontwait(runtime.NewPacket([]byte(err.Error())))
			}
			continue
		}

		// Property output socket
		if propPort != nil {
			var data interface{}
			if strings.HasSuffix(request.ContentType, "json") {
				err = json.Unmarshal(resp.Body, &data)
				if err != nil {
					log.Println("ERROR unmarshaling the JSON response:", err.Error())
					continue
				}
			} else {
				// TODO: support other content-types
				log.Printf("WARNING processing of %s is not supported", request.ContentType)
				continue
			}

			prop, err := propTemplate.Fill(data)
			if err != nil {
				log.Println("ERROR filling template with data: ", err.Error())
				continue
			}

			out, _ := json.Marshal(prop)
			propPort.SendMessage(runtime.NewPacket(out))
		}

		// Extra output sockets (e.g., for debugging)
		if respPort != nil {
			ip, err = httputils.Response2IP(resp)
			if err != nil {
				log.Println("ERROR converting reply to IP:", err.Error())
				if errPort != nil {
					errPort.SendMessageDontwait(runtime.NewPacket([]byte(err.Error())))
				}
			} else {
				respPort.SendMessage(ip)
			}
		}
		if bodyPort != nil {
			bodyPort.SendMessage(runtime.NewPacket(resp.Body))
		}
	}
}