Files
zeekay 241625e7d9 rename: ziti → zt across all paths
- Repo names: ziti-* → zt-*
- Go modules: github.com/hanzozt/ziti → github.com/hanzozt/zt
- Docker images: hanzozt/ziti-* → hanzozt/zt-*
- C/Java/JS symbols: ziti_* → zt_*
- File and directory names updated
2026-02-18 18:34:19 -08:00

177 lines
4.8 KiB
Go

/*
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.
*/
package forwarder
import (
"fmt"
"reflect"
"sync/atomic"
"time"
"github.com/hanzozt/sdk-golang/xgress"
"github.com/hanzozt/zt/v2/router/env"
"github.com/orcaman/concurrent-map/v2"
)
// circuitTable implements a directory of forwardTables, keyed by circuitId.
type circuitTable struct {
circuits cmap.ConcurrentMap[string, *forwardTable]
}
func newCircuitTable() *circuitTable {
return &circuitTable{
circuits: cmap.New[*forwardTable](),
}
}
func (st *circuitTable) setForwardTable(circuitId string, ft *forwardTable) {
atomic.StoreInt64(&ft.last, time.Now().UnixMilli())
st.circuits.Set(circuitId, ft)
}
func (st *circuitTable) getForwardTable(circuitId string, markActive bool) (*forwardTable, bool) {
if ft, found := st.circuits.Get(circuitId); found {
if markActive {
atomic.StoreInt64(&ft.last, time.Now().UnixMilli())
}
return ft, true
}
return nil, false
}
func (st *circuitTable) removeForwardTable(circuitId string) {
st.circuits.Remove(circuitId)
}
func (st *circuitTable) debug() string {
out := fmt.Sprintf("circuits (%d):\n", st.circuits.Count())
for i := range st.circuits.IterBuffered() {
out += "\n"
out += fmt.Sprintf("\tc/%s", i.Key)
out += i.Val.debug()
}
return out
}
// forwardTable implements a directory of destinations, keyed by source address.
type forwardTable struct {
ctrlId string
last int64
destinations cmap.ConcurrentMap[string, string]
}
func newForwardTable(ctrlId string) *forwardTable {
return &forwardTable{
ctrlId: ctrlId,
destinations: cmap.New[string](),
}
}
func (ft *forwardTable) setForwardAddress(src, dst xgress.Address) {
ft.destinations.Set(string(src), string(dst))
}
func (ft *forwardTable) getForwardAddress(src xgress.Address) (xgress.Address, bool) {
if dst, found := ft.destinations.Get(string(src)); found {
return xgress.Address(dst), true
}
return "", false
}
func (ft *forwardTable) debug() string {
out := ""
for i := range ft.destinations.IterBuffered() {
out += fmt.Sprintf("\t\t@/%s -> @/%s\n", i.Key, i.Val)
}
return out
}
// destinationTable implements a directory of destinations, keyed by Address.
type destinationTable struct {
destinations cmap.ConcurrentMap[string, env.Destination]
xgress cmap.ConcurrentMap[string, []xgress.Address]
}
func newDestinationTable() *destinationTable {
return &destinationTable{
destinations: cmap.New[env.Destination](),
xgress: cmap.New[[]xgress.Address](),
}
}
func (dt *destinationTable) addDestination(addr xgress.Address, destination env.Destination) {
dt.destinations.Set(string(addr), destination)
}
func (dt *destinationTable) getDestination(addr xgress.Address) (env.Destination, bool) {
if dst, found := dt.destinations.Get(string(addr)); found {
return dst, true
}
return nil, false
}
func (dt *destinationTable) removeDestination(addr xgress.Address) {
dt.destinations.Remove(string(addr))
}
func (dt *destinationTable) removeDestinationIfMatches(addr xgress.Address, destination env.Destination) {
dt.destinations.RemoveCb(string(addr), func(key string, v env.Destination, exists bool) bool {
return exists && destination == v
})
}
func (dt *destinationTable) linkDestinationToCircuit(circuitId string, address xgress.Address) {
var addresses []xgress.Address
if i, found := dt.xgress.Get(circuitId); found {
addresses = i
} else {
addresses = make([]xgress.Address, 0)
}
addresses = append(addresses, address)
dt.xgress.Set(circuitId, addresses)
}
func (dt *destinationTable) getAddressesForCircuit(circuitId string) ([]xgress.Address, bool) {
if addresses, found := dt.xgress.Get(circuitId); found {
return addresses, found
}
return nil, false
}
func (dt *destinationTable) unlinkCircuit(circuitId string) {
dt.xgress.Remove(circuitId)
}
func (dt *destinationTable) debug() string {
out := fmt.Sprintf("\ndestinations (%d):\n\n", dt.destinations.Count())
for i := range dt.destinations.IterBuffered() {
out += fmt.Sprintf("\t@/%s -> (%s (%p))\n", i.Key, reflect.TypeOf(i.Val).String(), i.Val)
}
out += "\n"
out += fmt.Sprintf("xgress (%d):\n\n", dt.xgress.Count())
for tuple := range dt.xgress.IterBuffered() {
out += fmt.Sprintf("\tc/%s:\n", tuple.Key)
addresses := tuple.Val
for _, address := range addresses {
out += fmt.Sprintf("\t\t@/%s\n", address)
}
}
out += "\n"
return out
}