From dc5054395a3fb695dfc9b029c75d5c94be9b8d8c Mon Sep 17 00:00:00 2001 From: Brandon Fulljames Date: Tue, 13 Dec 2022 20:44:22 +0900 Subject: [PATCH] Add simple send --- Makefile | 13 ++++++++++++- README.md | 19 ++++++++++++++----- cmd/cyn/root.go | 26 +++++++++++++++++++++++++- go.mod | 11 ----------- go.sum | 3 +++ pkg/sender/udp.go | 37 +++++++++++++++++++++++++++++++++++++ 6 files changed, 91 insertions(+), 18 deletions(-) create mode 100644 pkg/sender/udp.go diff --git a/Makefile b/Makefile index bca9812..e94d2f1 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,21 @@ .PHONY: build build: bin/cyn +.PHONY: build-all +build-all: bin/cyn bin/cyn-linux bin/cyn-mac bin/cyn-windows + # Build for local -bin/cyn: ./cmd/cyn/*.go ./pkg/listener/*.go +bin/cyn: ./cmd/cyn/*.go ./pkg/listener/*.go ./pkg/sender/*.go go build -o bin/cyn ./cmd/cyn/*.go +# Build for other OSes +bin/cyn-linux: ./cmd/cyn/*.go ./pkg/listener/*.go ./pkg/sender/*.go + CGO_ENABLED=0 GOOS=linux go build -o bin/cyn-linux ./cmd/cyn/*.go +bin/cyn-mac: ./cmd/cyn/*.go ./pkg/listener/*.go ./pkg/sender/*.go + CGO_ENABLED=0 GOOS=darwin go build -o bin/cyn-mac ./cmd/cyn/*.go +bin/cyn-windows: ./cmd/cyn/*.go ./pkg/listener/*.go ./pkg/sender/*.go + CGO_ENABLED=0 GOOS=windows go build -o bin/cyn-windows ./cmd/cyn/*.go + .PHONY: docker docker: docker build -t evertras/cyn:latest . diff --git a/README.md b/README.md index c04fa56..5e29ab2 100644 --- a/README.md +++ b/README.md @@ -25,17 +25,26 @@ Config file for more advanced setups. ## How to use it -For simple use cases, just use command line args. +For simple use cases, just use command line args. By convention, lowercase +means listen while uppercase means send. ```bash # On Machine A - 192.168.58.2 -cyn --listen-udp 192.168.58.1:1234 --call-tcp 192.168.58.3:3456 --call-tcp 192.168.58.4:3456 +cyn --listen-udp 192.168.58.2:1234 --send-udp 192.168.58.3:3456 --send-udp 192.168.58.4:3456 # On Machine B - 192.168.58.3 (shorthand flags) -cyn -l 192.168.58.2:2345 -t 192.168.58.2:1234 -t 192.168.58.4:3456 +cyn -u 192.168.58.3:2345 -U 192.168.58.2:1234 -U 192.168.58.4:3456 -# On Machine C - 192.168.58.4 (broadcasting) -cyn -l 192.168.58.3:3456 --broadcast 192.168.58.255 +# On Machine C - 192.168.58.4 (mixed) +cyn -u 192.168.58.4:3456 --send-udp 192.168.58.2:2345 +``` + +```bash +# Listen for broadcast messages on Machine A +cyn -u :1234 + +# Broadcast messages from Machine B using the regular UDP sender +cyn -U 192.168.58.255:1234 ``` ## Why the name diff --git a/cmd/cyn/root.go b/cmd/cyn/root.go index 3eee432..9f9db41 100644 --- a/cmd/cyn/root.go +++ b/cmd/cyn/root.go @@ -3,19 +3,23 @@ package main import ( "fmt" "net" + "time" "github.com/spf13/cobra" "golang.org/x/sync/errgroup" "github.com/evertras/cynomys/pkg/listener" + "github.com/evertras/cynomys/pkg/sender" ) var ( listenOnUDPList []string + sendUDPToList []string ) func init() { - rootCmd.Flags().StringSliceVarP(&listenOnUDPList, "listen-udp", "l", nil, "An IP:port address to listen on for UDP. Can be specified multiple times.") + rootCmd.Flags().StringSliceVarP(&listenOnUDPList, "listen-udp", "u", nil, "An IP:port address to listen on for UDP. Can be specified multiple times.") + rootCmd.Flags().StringSliceVarP(&sendUDPToList, "send-udp", "U", nil, "An IP:port address to send to (UDP). Can be specified multiple times.") } var rootCmd = &cobra.Command{ @@ -36,6 +40,26 @@ var rootCmd = &cobra.Command{ }) } + for _, sendUDPTo := range sendUDPToList { + addr, err := net.ResolveUDPAddr("udp", sendUDPTo) + + if err != nil { + return fmt.Errorf("net.ResolveUDPAddr for %q: %w", sendUDPTo, err) + } + + eg.Go(func() error { + c := sender.NewUDPSender(*addr) + + for { + err := c.Send([]byte("hi")) + if err != nil { + return fmt.Errorf("c.Send: %w", err) + } + time.Sleep(time.Second) + } + }) + } + return eg.Wait() }, } diff --git a/go.mod b/go.mod index d3910b0..321e179 100644 --- a/go.mod +++ b/go.mod @@ -7,14 +7,3 @@ require ( github.com/spf13/cobra v1.1.1 golang.org/x/sync v0.0.0-20190423024810-112230192c58 ) - -require ( - github.com/cucumber/gherkin-go/v19 v19.0.3 // indirect - github.com/cucumber/messages-go/v16 v16.0.1 // indirect - github.com/gofrs/uuid v4.0.0+incompatible // indirect - github.com/hashicorp/go-immutable-radix v1.3.0 // indirect - github.com/hashicorp/go-memdb v1.3.0 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect -) diff --git a/go.sum b/go.sum index c0465b6..9c395d3 100644 --- a/go.sum +++ b/go.sum @@ -120,8 +120,10 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -299,6 +301,7 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/pkg/sender/udp.go b/pkg/sender/udp.go new file mode 100644 index 0000000..b3b09b4 --- /dev/null +++ b/pkg/sender/udp.go @@ -0,0 +1,37 @@ +package sender + +import ( + "fmt" + "net" +) + +type UDPSender struct { + broadcastAddr net.UDPAddr + conn *net.UDPConn +} + +func NewUDPSender(addr net.UDPAddr) *UDPSender { + return &UDPSender{ + broadcastAddr: addr, + } +} + +func (s *UDPSender) Send(data []byte) error { + if s.conn == nil { + c, err := net.DialUDP("udp4", nil, &s.broadcastAddr) + + if err != nil { + return fmt.Errorf("net.DialUDP: %w", err) + } + + s.conn = c + } + + _, err := s.conn.Write(data) + + if err != nil { + return fmt.Errorf("s.conn.Write: %w", err) + } + + return nil +}