-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.swift
154 lines (133 loc) · 4.71 KB
/
main.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
Copyright NetFoundry Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import Foundation
import CZiti
var ziti:Ziti?
// Server callbacks
let onListen:ZitiConnection.ListenCallback = { serv, status in
let statMsg = Ziti.zitiErrorString(status: status)
if (status == Ziti.ZITI_OK) {
print("Byte Counter is ready! \(status)(\(statMsg))")
}
else {
fputs("ERROR The Byte Counter could not be started: \(status)(\(statMsg))\n", stderr)
serv.close()
}
}
let onAccept:ZitiConnection.ConnCallback = { conn, status in
guard status == Ziti.ZITI_OK else {
let errStr = Ziti.zitiErrorString(status: status)
fputs("Client accept error: \(status)(\(errStr))\n", stderr)
return
}
if let msg = String("Hello from byte counter!\n").data(using: .utf8) {
conn.write(msg) { _, len in
guard len >= 0 else {
let errStr = Ziti.zitiErrorString(status: Int32(len))
fputs("Connected client write error: \(len)(\(errStr)\n", stderr)
return
}
print("Sent \(len) bytes to connected client")
}
}
}
let onDataFromClient:ZitiConnection.DataCallback = { conn, data, len in
guard len > 0 else {
let errStr = Ziti.zitiErrorString(status: Int32(len))
fputs("onDataFromClient: \(len)(\(errStr)\n", stderr)
return 0
}
let msg = data != nil ? (String(data: data!, encoding: .utf8) ?? "") : ""
print("client sent us \(len) bytes, msg: \(msg)")
// write back num bytes conn.write(...)
if let response = String("\(len)").data(using: .utf8) {
print("Responding to client with \(len)")
conn.write(response) { _, len in
guard len >= 0 else {
let errStr = Ziti.zitiErrorString(status: Int32(len))
fputs("Error writing to client: \(len)(\(errStr)\n", stderr)
return
}
print("Sent \(len) bytes to client")
}
}
return data?.count ?? 0
}
// Client callbacks
let onDial:ZitiConnection.ConnCallback = { conn, status in
guard status == Ziti.ZITI_OK else {
let errStr = Ziti.zitiErrorString(status: status)
fputs("onDial :\(status)(\(errStr)", stderr)
return
}
if let msg = String("hello").data(using: .utf8) {
conn.write(msg) { _, len in
guard len >= 0 else {
let errStr = Ziti.zitiErrorString(status: Int32(len))
fputs("Dialed connection write error: \(len)(\(errStr)\n", stderr)
return
}
print("Sent \(len) bytes to server")
}
}
}
let onDataFromServer:ZitiConnection.DataCallback = { conn, data, len in
guard len > 0 else {
let errStr = Ziti.zitiErrorString(status: Int32(len))
fputs("onDataFromServer: \(len)\(errStr)", stderr)
conn.close()
ziti?.shutdown()
return 0
}
let msg = data != nil ? (String(data: data!, encoding: .utf8) ?? "") : ""
print("Server sent us \(len) bytes, msg: \(msg)")
return data?.count ?? 0
}
// Parse command line
let args = CommandLine.arguments
if CommandLine.argc != 4 {
fputs("Usage: \(args[0]) <client|server> <config-file> <service-name>\n", stderr);
exit(1);
}
let isServer = (args[1] == "server")
print("Running as \(isServer ? "server" : "client")")
let zidFile = args[2]
let service = args[3]
// Load ziti instance from zid file
ziti = Ziti(fromFile: zidFile)
guard let ziti = ziti else {
fputs("Unable to load Ziti from zid file \(zidFile)\n", stderr)
exit(1)
}
// Run ziti
ziti.run { zErr in
guard zErr == nil else {
fputs("Unable to run ziti \(String(describing: zErr))\n", stderr)
exit(1)
}
guard let conn = ziti.createConnection() else {
fputs("Unable to create connection\n", stderr)
exit(1)
}
if isServer {
conn.listen(service, onListen) { server, client, status in
guard status == Ziti.ZITI_OK else {
fputs("onClient \(status): \(Ziti.zitiErrorString(status: status))", stderr)
return
}
client.accept(onAccept, onDataFromClient)
}
} else {
conn.dial(service, onDial, onDataFromServer)
}
}