Integrate BACKBEAT SDK and resolve KACHING license validation

Major integrations and fixes:
- Added BACKBEAT SDK integration for P2P operation timing
- Implemented beat-aware status tracking for distributed operations
- Added Docker secrets support for secure license management
- Resolved KACHING license validation via HTTPS/TLS
- Updated docker-compose configuration for clean stack deployment
- Disabled rollback policies to prevent deployment failures
- Added license credential storage (CHORUS-DEV-MULTI-001)

Technical improvements:
- BACKBEAT P2P operation tracking with phase management
- Enhanced configuration system with file-based secrets
- Improved error handling for license validation
- Clean separation of KACHING and CHORUS deployment stacks

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
anthonyrawlins
2025-09-06 07:56:26 +10:00
parent 543ab216f9
commit 9bdcbe0447
4730 changed files with 1480093 additions and 1916 deletions

13
vendor/github.com/jackpal/go-nat-pmp/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,13 @@
language: go
go:
- 1.13.4
- tip
allowed_failures:
- go: tip
install:
- go get -d -v ./... && go install -race -v ./...
script: go test -race -v ./...

13
vendor/github.com/jackpal/go-nat-pmp/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,13 @@
Copyright 2013 John Howard Palevich
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
http://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.

78
vendor/github.com/jackpal/go-nat-pmp/README.md generated vendored Normal file
View File

@@ -0,0 +1,78 @@
go-nat-pmp
==========
A Go language client for the NAT-PMP internet protocol for port mapping and discovering the external
IP address of a firewall.
NAT-PMP is supported by Apple brand routers and open source routers like Tomato and DD-WRT.
See https://tools.ietf.org/rfc/rfc6886.txt
[![Build Status](https://travis-ci.org/jackpal/go-nat-pmp.svg)](https://travis-ci.org/jackpal/go-nat-pmp)
Get the package
---------------
# Get the go-nat-pmp package.
go get -u github.com/jackpal/go-nat-pmp
Usage
-----
Get one more package, used by the example code:
go get -u github.com/jackpal/gateway
Create a directory:
cd ~/go
mkdir -p src/hello
cd src/hello
Create a file hello.go with these contents:
package main
import (
"fmt"
"github.com/jackpal/gateway"
natpmp "github.com/jackpal/go-nat-pmp"
)
func main() {
gatewayIP, err := gateway.DiscoverGateway()
if err != nil {
return
}
client := natpmp.NewClient(gatewayIP)
response, err := client.GetExternalAddress()
if err != nil {
return
}
fmt.Printf("External IP address: %v\n", response.ExternalIPAddress)
}
Build the example
go build
./hello
External IP address: [www xxx yyy zzz]
Clients
-------
This library is used in the Taipei Torrent BitTorrent client http://github.com/jackpal/Taipei-Torrent
Complete documentation
----------------------
http://godoc.org/github.com/jackpal/go-nat-pmp
License
-------
This project is licensed under the Apache License 2.0.

157
vendor/github.com/jackpal/go-nat-pmp/natpmp.go generated vendored Normal file
View File

@@ -0,0 +1,157 @@
package natpmp
import (
"fmt"
"net"
"time"
)
// Implement the NAT-PMP protocol, typically supported by Apple routers and open source
// routers such as DD-WRT and Tomato.
//
// See https://tools.ietf.org/rfc/rfc6886.txt
//
// Usage:
//
// client := natpmp.NewClient(gatewayIP)
// response, err := client.GetExternalAddress()
// The recommended mapping lifetime for AddPortMapping.
const RECOMMENDED_MAPPING_LIFETIME_SECONDS = 3600
// Interface used to make remote procedure calls.
type caller interface {
call(msg []byte, timeout time.Duration) (result []byte, err error)
}
// Client is a NAT-PMP protocol client.
type Client struct {
caller caller
timeout time.Duration
}
// Create a NAT-PMP client for the NAT-PMP server at the gateway.
// Uses default timeout which is around 128 seconds.
func NewClient(gateway net.IP) (nat *Client) {
return &Client{&network{gateway}, 0}
}
// Create a NAT-PMP client for the NAT-PMP server at the gateway, with a timeout.
// Timeout defines the total amount of time we will keep retrying before giving up.
func NewClientWithTimeout(gateway net.IP, timeout time.Duration) (nat *Client) {
return &Client{&network{gateway}, timeout}
}
// Results of the NAT-PMP GetExternalAddress operation.
type GetExternalAddressResult struct {
SecondsSinceStartOfEpoc uint32
ExternalIPAddress [4]byte
}
// Get the external address of the router.
//
// Note that this call can take up to 128 seconds to return.
func (n *Client) GetExternalAddress() (result *GetExternalAddressResult, err error) {
msg := make([]byte, 2)
msg[0] = 0 // Version 0
msg[1] = 0 // OP Code 0
response, err := n.rpc(msg, 12)
if err != nil {
return
}
result = &GetExternalAddressResult{}
result.SecondsSinceStartOfEpoc = readNetworkOrderUint32(response[4:8])
copy(result.ExternalIPAddress[:], response[8:12])
return
}
// Results of the NAT-PMP AddPortMapping operation
type AddPortMappingResult struct {
SecondsSinceStartOfEpoc uint32
InternalPort uint16
MappedExternalPort uint16
PortMappingLifetimeInSeconds uint32
}
// Add (or delete) a port mapping. To delete a mapping, set the requestedExternalPort and lifetime to 0.
// Note that this call can take up to 128 seconds to return.
func (n *Client) AddPortMapping(protocol string, internalPort, requestedExternalPort int, lifetime int) (result *AddPortMappingResult, err error) {
var opcode byte
if protocol == "udp" {
opcode = 1
} else if protocol == "tcp" {
opcode = 2
} else {
err = fmt.Errorf("unknown protocol %v", protocol)
return
}
msg := make([]byte, 12)
msg[0] = 0 // Version 0
msg[1] = opcode
// [2:3] is reserved.
writeNetworkOrderUint16(msg[4:6], uint16(internalPort))
writeNetworkOrderUint16(msg[6:8], uint16(requestedExternalPort))
writeNetworkOrderUint32(msg[8:12], uint32(lifetime))
response, err := n.rpc(msg, 16)
if err != nil {
return
}
result = &AddPortMappingResult{}
result.SecondsSinceStartOfEpoc = readNetworkOrderUint32(response[4:8])
result.InternalPort = readNetworkOrderUint16(response[8:10])
result.MappedExternalPort = readNetworkOrderUint16(response[10:12])
result.PortMappingLifetimeInSeconds = readNetworkOrderUint32(response[12:16])
return
}
func (n *Client) rpc(msg []byte, resultSize int) (result []byte, err error) {
result, err = n.caller.call(msg, n.timeout)
if err != nil {
return
}
err = protocolChecks(msg, resultSize, result)
return
}
func protocolChecks(msg []byte, resultSize int, result []byte) (err error) {
if len(result) != resultSize {
err = fmt.Errorf("unexpected result size %d, expected %d", len(result), resultSize)
return
}
if result[0] != 0 {
err = fmt.Errorf("unknown protocol version %d", result[0])
return
}
expectedOp := msg[1] | 0x80
if result[1] != expectedOp {
err = fmt.Errorf("Unexpected opcode %d. Expected %d", result[1], expectedOp)
return
}
resultCode := readNetworkOrderUint16(result[2:4])
if resultCode != 0 {
err = fmt.Errorf("Non-zero result code %d", resultCode)
return
}
// If we got here the RPC is good.
return
}
func writeNetworkOrderUint16(buf []byte, d uint16) {
buf[0] = byte(d >> 8)
buf[1] = byte(d)
}
func writeNetworkOrderUint32(buf []byte, d uint32) {
buf[0] = byte(d >> 24)
buf[1] = byte(d >> 16)
buf[2] = byte(d >> 8)
buf[3] = byte(d)
}
func readNetworkOrderUint16(buf []byte) uint16 {
return (uint16(buf[0]) << 8) | uint16(buf[1])
}
func readNetworkOrderUint32(buf []byte) uint32 {
return (uint32(buf[0]) << 24) | (uint32(buf[1]) << 16) | (uint32(buf[2]) << 8) | uint32(buf[3])
}

89
vendor/github.com/jackpal/go-nat-pmp/network.go generated vendored Normal file
View File

@@ -0,0 +1,89 @@
package natpmp
import (
"fmt"
"net"
"time"
)
const nAT_PMP_PORT = 5351
const nAT_TRIES = 9
const nAT_INITIAL_MS = 250
// A caller that implements the NAT-PMP RPC protocol.
type network struct {
gateway net.IP
}
func (n *network) call(msg []byte, timeout time.Duration) (result []byte, err error) {
var server net.UDPAddr
server.IP = n.gateway
server.Port = nAT_PMP_PORT
conn, err := net.DialUDP("udp", nil, &server)
if err != nil {
return
}
defer conn.Close()
// 16 bytes is the maximum result size.
result = make([]byte, 16)
var finalTimeout time.Time
if timeout != 0 {
finalTimeout = time.Now().Add(timeout)
}
needNewDeadline := true
var tries uint
for tries = 0; (tries < nAT_TRIES && finalTimeout.IsZero()) || time.Now().Before(finalTimeout); {
if needNewDeadline {
nextDeadline := time.Now().Add((nAT_INITIAL_MS << tries) * time.Millisecond)
err = conn.SetDeadline(minTime(nextDeadline, finalTimeout))
if err != nil {
return
}
needNewDeadline = false
}
_, err = conn.Write(msg)
if err != nil {
return
}
var bytesRead int
var remoteAddr *net.UDPAddr
bytesRead, remoteAddr, err = conn.ReadFromUDP(result)
if err != nil {
if err.(net.Error).Timeout() {
tries++
needNewDeadline = true
continue
}
return
}
if !remoteAddr.IP.Equal(n.gateway) {
// Ignore this packet.
// Continue without increasing retransmission timeout or deadline.
continue
}
// Trim result to actual number of bytes received
if bytesRead < len(result) {
result = result[:bytesRead]
}
return
}
err = fmt.Errorf("Timed out trying to contact gateway")
return
}
func minTime(a, b time.Time) time.Time {
if a.IsZero() {
return b
}
if b.IsZero() {
return a
}
if a.Before(b) {
return a
}
return b
}

19
vendor/github.com/jackpal/go-nat-pmp/recorder.go generated vendored Normal file
View File

@@ -0,0 +1,19 @@
package natpmp
import "time"
type callObserver interface {
observeCall(msg []byte, result []byte, err error)
}
// A caller that records the RPC call.
type recorder struct {
child caller
observer callObserver
}
func (n *recorder) call(msg []byte, timeout time.Duration) (result []byte, err error) {
result, err = n.child.call(msg, timeout)
n.observer.observeCall(msg, result, err)
return
}