 9bdcbe0447
			
		
	
	9bdcbe0447
	
	
	
		
			
			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>
		
			
				
	
	
		
			359 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			359 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package manet
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 	"net"
 | |
| 	"path/filepath"
 | |
| 	"runtime"
 | |
| 	"strings"
 | |
| 
 | |
| 	ma "github.com/multiformats/go-multiaddr"
 | |
| )
 | |
| 
 | |
| var errIncorrectNetAddr = fmt.Errorf("incorrect network addr conversion")
 | |
| var errNotIP = fmt.Errorf("multiaddr does not start with an IP address")
 | |
| 
 | |
| // FromNetAddr converts a net.Addr type to a Multiaddr.
 | |
| func FromNetAddr(a net.Addr) (ma.Multiaddr, error) {
 | |
| 	return defaultCodecs.FromNetAddr(a)
 | |
| }
 | |
| 
 | |
| // FromNetAddr converts a net.Addr to Multiaddress.
 | |
| func (cm *CodecMap) FromNetAddr(a net.Addr) (ma.Multiaddr, error) {
 | |
| 	if a == nil {
 | |
| 		return nil, fmt.Errorf("nil multiaddr")
 | |
| 	}
 | |
| 	p, err := cm.getAddrParser(a.Network())
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return p(a)
 | |
| }
 | |
| 
 | |
| // ToNetAddr converts a Multiaddr to a net.Addr
 | |
| // Must be ThinWaist. acceptable protocol stacks are:
 | |
| // /ip{4,6}/{tcp, udp}
 | |
| func ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) {
 | |
| 	return defaultCodecs.ToNetAddr(maddr)
 | |
| }
 | |
| 
 | |
| // ToNetAddr converts a Multiaddress to a standard net.Addr.
 | |
| func (cm *CodecMap) ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) {
 | |
| 	protos := maddr.Protocols()
 | |
| 	final := protos[len(protos)-1]
 | |
| 
 | |
| 	p, err := cm.getMaddrParser(final.Name)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return p(maddr)
 | |
| }
 | |
| 
 | |
| // MultiaddrToIPNet converts a multiaddr to an IPNet. Useful for seeing if another IP address is contained within this multiaddr network+mask
 | |
| func MultiaddrToIPNet(m ma.Multiaddr) (*net.IPNet, error) {
 | |
| 	var ipString string
 | |
| 	var mask string
 | |
| 
 | |
| 	ma.ForEach(m, func(c ma.Component) bool {
 | |
| 		if c.Protocol().Code == ma.P_IP4 || c.Protocol().Code == ma.P_IP6 {
 | |
| 			ipString = c.Value()
 | |
| 		}
 | |
| 		if c.Protocol().Code == ma.P_IPCIDR {
 | |
| 			mask = c.Value()
 | |
| 		}
 | |
| 		return ipString == "" || mask == ""
 | |
| 	})
 | |
| 
 | |
| 	if ipString == "" {
 | |
| 		return nil, errors.New("no ip protocol found")
 | |
| 	}
 | |
| 
 | |
| 	if mask == "" {
 | |
| 		return nil, errors.New("no mask found")
 | |
| 	}
 | |
| 
 | |
| 	_, ipnet, err := net.ParseCIDR(ipString + "/" + string(mask))
 | |
| 	return ipnet, err
 | |
| }
 | |
| 
 | |
| func parseBasicNetMaddr(maddr ma.Multiaddr) (net.Addr, error) {
 | |
| 	network, host, err := DialArgs(maddr)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	switch network {
 | |
| 	case "tcp", "tcp4", "tcp6":
 | |
| 		return net.ResolveTCPAddr(network, host)
 | |
| 	case "udp", "udp4", "udp6":
 | |
| 		return net.ResolveUDPAddr(network, host)
 | |
| 	case "ip", "ip4", "ip6":
 | |
| 		return net.ResolveIPAddr(network, host)
 | |
| 	case "unix":
 | |
| 		return net.ResolveUnixAddr(network, host)
 | |
| 	}
 | |
| 
 | |
| 	return nil, fmt.Errorf("network not supported: %s", network)
 | |
| }
 | |
| 
 | |
| func FromIPAndZone(ip net.IP, zone string) (ma.Multiaddr, error) {
 | |
| 	switch {
 | |
| 	case ip.To4() != nil:
 | |
| 		return ma.NewComponent("ip4", ip.String())
 | |
| 	case ip.To16() != nil:
 | |
| 		ip6, err := ma.NewComponent("ip6", ip.String())
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		if zone == "" {
 | |
| 			return ip6, nil
 | |
| 		} else {
 | |
| 			zone, err := ma.NewComponent("ip6zone", zone)
 | |
| 			if err != nil {
 | |
| 				return nil, err
 | |
| 			}
 | |
| 			return zone.Encapsulate(ip6), nil
 | |
| 		}
 | |
| 	default:
 | |
| 		return nil, errIncorrectNetAddr
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // FromIP converts a net.IP type to a Multiaddr.
 | |
| func FromIP(ip net.IP) (ma.Multiaddr, error) {
 | |
| 	return FromIPAndZone(ip, "")
 | |
| }
 | |
| 
 | |
| // ToIP converts a Multiaddr to a net.IP when possible
 | |
| func ToIP(addr ma.Multiaddr) (net.IP, error) {
 | |
| 	var ip net.IP
 | |
| 	ma.ForEach(addr, func(c ma.Component) bool {
 | |
| 		switch c.Protocol().Code {
 | |
| 		case ma.P_IP6ZONE:
 | |
| 			// we can't return these anyways.
 | |
| 			return true
 | |
| 		case ma.P_IP6, ma.P_IP4:
 | |
| 			ip = net.IP(c.RawValue())
 | |
| 			return false
 | |
| 		}
 | |
| 		return false
 | |
| 	})
 | |
| 	if ip == nil {
 | |
| 		return nil, errNotIP
 | |
| 	}
 | |
| 	return ip, nil
 | |
| }
 | |
| 
 | |
| // DialArgs is a convenience function that returns network and address as
 | |
| // expected by net.Dial. See https://godoc.org/net#Dial for an overview of
 | |
| // possible return values (we do not support the unixpacket ones yet). Unix
 | |
| // addresses do not, at present, compose.
 | |
| func DialArgs(m ma.Multiaddr) (string, string, error) {
 | |
| 	zone, network, ip, port, hostname, err := dialArgComponents(m)
 | |
| 	if err != nil {
 | |
| 		return "", "", err
 | |
| 	}
 | |
| 
 | |
| 	// If we have a hostname (dns*), we don't want any fancy ipv6 formatting
 | |
| 	// logic (zone, brackets, etc.).
 | |
| 	if hostname {
 | |
| 		switch network {
 | |
| 		case "ip", "ip4", "ip6":
 | |
| 			return network, ip, nil
 | |
| 		case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6":
 | |
| 			return network, ip + ":" + port, nil
 | |
| 		}
 | |
| 		// Hostname is only true when network is one of the above.
 | |
| 		panic("unreachable")
 | |
| 	}
 | |
| 
 | |
| 	switch network {
 | |
| 	case "ip6":
 | |
| 		if zone != "" {
 | |
| 			ip += "%" + zone
 | |
| 		}
 | |
| 		fallthrough
 | |
| 	case "ip4":
 | |
| 		return network, ip, nil
 | |
| 	case "tcp4", "udp4":
 | |
| 		return network, ip + ":" + port, nil
 | |
| 	case "tcp6", "udp6":
 | |
| 		if zone != "" {
 | |
| 			ip += "%" + zone
 | |
| 		}
 | |
| 		return network, "[" + ip + "]" + ":" + port, nil
 | |
| 	case "unix":
 | |
| 		if runtime.GOOS == "windows" {
 | |
| 			// convert /c:/... to c:\...
 | |
| 			ip = filepath.FromSlash(strings.TrimLeft(ip, "/"))
 | |
| 		}
 | |
| 		return network, ip, nil
 | |
| 	default:
 | |
| 		return "", "", fmt.Errorf("%s is not a 'thin waist' address", m)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // dialArgComponents extracts the raw pieces used in dialing a Multiaddr
 | |
| func dialArgComponents(m ma.Multiaddr) (zone, network, ip, port string, hostname bool, err error) {
 | |
| 	ma.ForEach(m, func(c ma.Component) bool {
 | |
| 		switch network {
 | |
| 		case "":
 | |
| 			switch c.Protocol().Code {
 | |
| 			case ma.P_IP6ZONE:
 | |
| 				if zone != "" {
 | |
| 					err = fmt.Errorf("%s has multiple zones", m)
 | |
| 					return false
 | |
| 				}
 | |
| 				zone = c.Value()
 | |
| 				return true
 | |
| 			case ma.P_IP6:
 | |
| 				network = "ip6"
 | |
| 				ip = c.Value()
 | |
| 				return true
 | |
| 			case ma.P_IP4:
 | |
| 				if zone != "" {
 | |
| 					err = fmt.Errorf("%s has ip4 with zone", m)
 | |
| 					return false
 | |
| 				}
 | |
| 				network = "ip4"
 | |
| 				ip = c.Value()
 | |
| 				return true
 | |
| 			case ma.P_DNS:
 | |
| 				network = "ip"
 | |
| 				hostname = true
 | |
| 				ip = c.Value()
 | |
| 				return true
 | |
| 			case ma.P_DNS4:
 | |
| 				network = "ip4"
 | |
| 				hostname = true
 | |
| 				ip = c.Value()
 | |
| 				return true
 | |
| 			case ma.P_DNS6:
 | |
| 				network = "ip6"
 | |
| 				hostname = true
 | |
| 				ip = c.Value()
 | |
| 				return true
 | |
| 			case ma.P_UNIX:
 | |
| 				network = "unix"
 | |
| 				ip = c.Value()
 | |
| 				return false
 | |
| 			}
 | |
| 		case "ip":
 | |
| 			switch c.Protocol().Code {
 | |
| 			case ma.P_UDP:
 | |
| 				network = "udp"
 | |
| 			case ma.P_TCP:
 | |
| 				network = "tcp"
 | |
| 			default:
 | |
| 				return false
 | |
| 			}
 | |
| 			port = c.Value()
 | |
| 		case "ip4":
 | |
| 			switch c.Protocol().Code {
 | |
| 			case ma.P_UDP:
 | |
| 				network = "udp4"
 | |
| 			case ma.P_TCP:
 | |
| 				network = "tcp4"
 | |
| 			default:
 | |
| 				return false
 | |
| 			}
 | |
| 			port = c.Value()
 | |
| 		case "ip6":
 | |
| 			switch c.Protocol().Code {
 | |
| 			case ma.P_UDP:
 | |
| 				network = "udp6"
 | |
| 			case ma.P_TCP:
 | |
| 				network = "tcp6"
 | |
| 			default:
 | |
| 				return false
 | |
| 			}
 | |
| 			port = c.Value()
 | |
| 		}
 | |
| 		// Done.
 | |
| 		return false
 | |
| 	})
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func parseTCPNetAddr(a net.Addr) (ma.Multiaddr, error) {
 | |
| 	ac, ok := a.(*net.TCPAddr)
 | |
| 	if !ok {
 | |
| 		return nil, errIncorrectNetAddr
 | |
| 	}
 | |
| 
 | |
| 	// Get IP Addr
 | |
| 	ipm, err := FromIPAndZone(ac.IP, ac.Zone)
 | |
| 	if err != nil {
 | |
| 		return nil, errIncorrectNetAddr
 | |
| 	}
 | |
| 
 | |
| 	// Get TCP Addr
 | |
| 	tcpm, err := ma.NewMultiaddr(fmt.Sprintf("/tcp/%d", ac.Port))
 | |
| 	if err != nil {
 | |
| 		return nil, errIncorrectNetAddr
 | |
| 	}
 | |
| 
 | |
| 	// Encapsulate
 | |
| 	return ipm.Encapsulate(tcpm), nil
 | |
| }
 | |
| 
 | |
| func parseUDPNetAddr(a net.Addr) (ma.Multiaddr, error) {
 | |
| 	ac, ok := a.(*net.UDPAddr)
 | |
| 	if !ok {
 | |
| 		return nil, errIncorrectNetAddr
 | |
| 	}
 | |
| 
 | |
| 	// Get IP Addr
 | |
| 	ipm, err := FromIPAndZone(ac.IP, ac.Zone)
 | |
| 	if err != nil {
 | |
| 		return nil, errIncorrectNetAddr
 | |
| 	}
 | |
| 
 | |
| 	// Get UDP Addr
 | |
| 	udpm, err := ma.NewMultiaddr(fmt.Sprintf("/udp/%d", ac.Port))
 | |
| 	if err != nil {
 | |
| 		return nil, errIncorrectNetAddr
 | |
| 	}
 | |
| 
 | |
| 	// Encapsulate
 | |
| 	return ipm.Encapsulate(udpm), nil
 | |
| }
 | |
| 
 | |
| func parseIPNetAddr(a net.Addr) (ma.Multiaddr, error) {
 | |
| 	ac, ok := a.(*net.IPAddr)
 | |
| 	if !ok {
 | |
| 		return nil, errIncorrectNetAddr
 | |
| 	}
 | |
| 	return FromIPAndZone(ac.IP, ac.Zone)
 | |
| }
 | |
| 
 | |
| func parseIPPlusNetAddr(a net.Addr) (ma.Multiaddr, error) {
 | |
| 	ac, ok := a.(*net.IPNet)
 | |
| 	if !ok {
 | |
| 		return nil, errIncorrectNetAddr
 | |
| 	}
 | |
| 	return FromIP(ac.IP)
 | |
| }
 | |
| 
 | |
| func parseUnixNetAddr(a net.Addr) (ma.Multiaddr, error) {
 | |
| 	ac, ok := a.(*net.UnixAddr)
 | |
| 	if !ok {
 | |
| 		return nil, errIncorrectNetAddr
 | |
| 	}
 | |
| 
 | |
| 	path := ac.Name
 | |
| 	if runtime.GOOS == "windows" {
 | |
| 		// Convert c:\foobar\... to c:/foobar/...
 | |
| 		path = filepath.ToSlash(path)
 | |
| 	}
 | |
| 	if len(path) == 0 || path[0] != '/' {
 | |
| 		// convert "" and "c:/..." to "/..."
 | |
| 		path = "/" + path
 | |
| 	}
 | |
| 
 | |
| 	return ma.NewComponent("unix", path)
 | |
| }
 |