-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #651 from openziti/udp-offload-example
Udp offload example
- Loading branch information
Showing
7 changed files
with
347 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# Overview | ||
This example illustrates how to send data to, and receive data from a UDP server via OpenZiti. | ||
You will configure an OpenZiti overlay network and run a UDP server that will respond with whatever text it was sent. | ||
The response from the server will be read written to the console. | ||
|
||
This example demonstrates a hybrid approach ZTAA --> ZTHA: | ||
* Dialing a service | ||
* Binding a service using a tunneler | ||
|
||
## Requirements | ||
* OpenZiti CLI to create services and identities on the OpenZiti Network | ||
* an OpenZiti network. If you have one you'd like to use, great. The guide is written using the | ||
`ziti edge quickstart` command. | ||
* All commands are executed relative to the `example` folder | ||
|
||
## Build the examples | ||
Refer to the [example README](../README.md) to build the SDK examples | ||
|
||
## Run and Configure OpenZiti | ||
The README assumes the `ziti` CLI on your path. If not, supply the full path to the `ziti` executable. This command | ||
will start a ziti overlay network on ports 1280/3022 for use with the rest of the README. The default values will | ||
also be used for username and password. The router from the quickstart is the identity which will offload the OpenZiti | ||
traffic toward the UDP server | ||
|
||
In a new terminal run the following command: | ||
``` | ||
ziti edge quickstart | ||
``` | ||
|
||
To configure the overlay, you will need another terminal with `ziti` on the path. Now, add a service for the UDP | ||
server to be offloaded from the OpenZiti overlay as well as create the identity this example will use: | ||
``` | ||
svc_name="udp.relay.example" | ||
edge_router_name="quickstart-router" | ||
ziti edge login localhost:1280 -u admin -p admin -y | ||
ziti edge create config ${svc_name}.hostv1 host.v1 '{"protocol":"udp", "address":"127.0.0.1","port":10001}' | ||
ziti edge create service ${svc_name} --configs "${svc_name}.hostv1" | ||
ziti edge create service-policy ${svc_name}.dial Dial --identity-roles "#${svc_name}.dialers" --service-roles "@${svc_name}" | ||
ziti edge create service-policy ${svc_name}.bind Bind --identity-roles "#${svc_name}.binders" --service-roles "@${svc_name}" | ||
ziti edge create identity ${svc_name}.client -a ${svc_name}.dialers -o ${svc_name}.client.jwt | ||
ziti edge enroll --jwt ${svc_name}.client.jwt | ||
ziti edge update identity ${edge_router_name} -a "${svc_name}.binders" | ||
ziti edge policy-advisor services -q | ||
``` | ||
|
||
## Run the UDP Server | ||
In the terminal from where you configured the OpenZiti overlay start the UDP server. Make sure you're in the | ||
`example` folder and run: | ||
``` | ||
./build/udp-server | ||
``` | ||
|
||
You should now have a UDP server that is listening on port 10001 and will respond to UDP messages sent to it. | ||
``` | ||
$ ./build/udp-server | ||
Listening on :10001 | ||
``` | ||
|
||
## Run the Example | ||
Make sure the router (or identity) hosting the service establishes a terminator. Issue the following command and verify | ||
a terminator is listed as shown: | ||
``` | ||
ziti edge list terminators 'service.name="udp.relay.example"' | ||
``` | ||
|
||
example output: | ||
``` | ||
$ ziti edge list terminators 'service.name="udp.relay.example"' | ||
╭───────────────────────┬───────────────────┬───────────────────┬─────────┬───────────────────────┬──────────┬──────┬────────────┬──────────────╮ | ||
│ ID │ SERVICE │ ROUTER │ BINDING │ ADDRESS │ IDENTITY │ COST │ PRECEDENCE │ DYNAMIC COST │ | ||
├───────────────────────┼───────────────────┼───────────────────┼─────────┼───────────────────────┼──────────┼──────┼────────────┼──────────────┤ | ||
│ sNVBPDKuI6q5I0f2PrEc6 │ udp.relay.example │ quickstart-router │ tunnel │ sNVBPDKuI6q5I0f2PrEc6 │ │ 0 │ default │ 0 │ | ||
╰───────────────────────┴───────────────────┴───────────────────┴─────────┴───────────────────────┴──────────┴──────┴────────────┴──────────────╯ | ||
results: 1-1 of 1 | ||
``` | ||
|
||
With the terminator in place, run the sample | ||
``` | ||
./build/udp-offload-client ./udp.relay.example.client.json | ||
``` | ||
|
||
example output: | ||
``` | ||
$ ./build/udp-offload-client ./udp.relay.example.client.json | ||
INFO[0000] found service named: udp.relay.example | ||
INFO[0000] Connected to udp.relay.example successfully. | ||
INFO[0000] You may now type a line to be sent to the server (press enter to send) | ||
INFO[0000] The line will be sent to the reflect server and returned | ||
this is the udp example | ||
wrote 24 bytes | ||
Sent :this is the udp example | ||
Received: udp server echo: this is the udp example | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"github.com/michaelquigley/pfxlog" | ||
"github.com/openziti/sdk-golang/ziti" | ||
"io" | ||
"os" | ||
) | ||
|
||
var log = pfxlog.Logger() | ||
|
||
func main() { | ||
serviceName := "udp.relay.example" | ||
|
||
zitiCfg, err := ziti.NewConfigFromFile(os.Args[1]) | ||
if err != nil { | ||
log.Fatalf("failed to load ziti configuration file: %v", err) | ||
} | ||
zitiCfg.ConfigTypes = []string{ | ||
"ziti-tunneler-client.v1", | ||
} | ||
|
||
ctx, err := ziti.NewContext(zitiCfg) | ||
if err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} | ||
|
||
foundSvc, ok := ctx.GetService(serviceName) | ||
if !ok { | ||
fmt.Println("error when retrieving all the services for the provided config") | ||
os.Exit(1) | ||
} | ||
log.Infof("found service named: %s", *foundSvc.Name) | ||
|
||
svc, err := ctx.Dial(serviceName) //dial the service using the given name | ||
if err != nil { | ||
fmt.Println(fmt.Sprintf("error when dialing service name %s. %v", serviceName, err)) | ||
os.Exit(1) | ||
} | ||
|
||
go ReadFromZiti(svc) | ||
log.Infof("Connected to %s successfully.", serviceName) | ||
log.Info("You may now type a line to be sent to the server (press enter to send)") | ||
log.Info("The line will be sent to the reflect server and returned") | ||
ReadFromConsole(svc) | ||
} | ||
|
||
func ReadFromConsole(writer io.Writer) { | ||
conWrite := bufio.NewWriter(writer) | ||
reader := bufio.NewReader(os.Stdin) | ||
for { | ||
text, err := reader.ReadString('\n') //read a line from input | ||
if err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} | ||
bytesRead, err := conWrite.WriteString(text) | ||
_ = conWrite.Flush() | ||
if err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} else { | ||
fmt.Println("wrote", bytesRead, "bytes") | ||
} | ||
fmt.Print("Sent :", text) | ||
} | ||
} | ||
|
||
func ReadFromZiti(reader io.Reader) { | ||
conRead := bufio.NewReader(reader) | ||
for { | ||
read, err := conRead.ReadString('\n') | ||
if err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} else { | ||
fmt.Print("Received: ", read) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
"os" | ||
) | ||
|
||
func main() { | ||
addr := ":10001" | ||
conn, err := net.ListenPacket("udp", addr) | ||
if err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} | ||
defer conn.Close() | ||
fmt.Printf("Listening on %s\n", addr) | ||
|
||
buf := make([]byte, 1024) | ||
for { | ||
n, remoteAddr, err := conn.ReadFrom(buf) | ||
if err != nil { | ||
fmt.Println("Error reading:", err) | ||
continue | ||
} | ||
|
||
fmt.Printf("%s sent: %s\n", remoteAddr, string(buf[:n-1])) | ||
|
||
_, err = conn.WriteTo([]byte("udp server echo: "), remoteAddr) | ||
if err != nil { | ||
fmt.Println("Error writing:", err) | ||
} | ||
_, err = conn.WriteTo(buf[:n], remoteAddr) | ||
if err != nil { | ||
fmt.Println("Error writing:", err) | ||
} | ||
} | ||
} |
Oops, something went wrong.