2018-05-27 22:22:50 +00:00
// +build debug
2017-12-29 04:16:20 +00:00
package yggdrasil
// These are functions that should not exist
// They are (or were) used during development, to work around missing features
// They're also used to configure things from the outside
// It would be better to define and export a few config functions elsewhere
// Or define some remote API and call it to send/request configuration info
import _ "golang.org/x/net/ipv6" // TODO put this somewhere better
2018-06-14 17:32:18 +00:00
//import "golang.org/x/net/proxy"
2018-04-26 14:23:21 +00:00
2017-12-29 04:16:20 +00:00
import "fmt"
import "net"
import "log"
2018-01-09 08:08:54 +00:00
import "regexp"
2017-12-29 04:16:20 +00:00
2018-05-27 22:22:50 +00:00
import _ "net/http/pprof"
import "net/http"
import "runtime"
2018-06-21 15:32:16 +00:00
import "os"
2018-07-09 08:38:48 +00:00
import "yggdrasil/defaults"
2018-06-21 15:32:16 +00:00
// Start the profiler in debug builds, if the required environment variable is set.
func init ( ) {
envVarName := "PPROFLISTEN"
hostPort := os . Getenv ( envVarName )
switch {
case hostPort == "" :
fmt . Printf ( "DEBUG: %s not set, profiler not started.\n" , envVarName )
default :
fmt . Printf ( "DEBUG: Starting pprof on %s\n" , hostPort )
go func ( ) { fmt . Println ( http . ListenAndServe ( hostPort , nil ) ) } ( )
}
}
2018-05-27 22:22:50 +00:00
// Starts the function profiler. This is only supported when built with
// '-tags build'.
func StartProfiler ( log * log . Logger ) error {
runtime . SetBlockProfileRate ( 1 )
go func ( ) { log . Println ( http . ListenAndServe ( "localhost:6060" , nil ) ) } ( )
return nil
}
2018-05-27 22:37:57 +00:00
// This function is only called by the simulator to set up a node with random
// keys. It should not be used and may be removed in the future.
func ( c * Core ) Init ( ) {
bpub , bpriv := newBoxKeys ( )
spub , spriv := newSigKeys ( )
c . init ( bpub , bpriv , spub , spriv )
2018-06-24 00:08:32 +00:00
c . switchTable . start ( )
2018-06-02 05:16:47 +00:00
c . router . start ( )
2018-05-27 22:37:57 +00:00
}
2018-05-27 22:22:50 +00:00
////////////////////////////////////////////////////////////////////////////////
2017-12-29 04:16:20 +00:00
// Core
2018-05-23 10:28:20 +00:00
func ( c * Core ) DEBUG_getSigningPublicKey ( ) sigPubKey {
2018-01-04 22:37:51 +00:00
return ( sigPubKey ) ( c . sigPub )
2017-12-29 04:16:20 +00:00
}
2018-05-23 10:28:20 +00:00
func ( c * Core ) DEBUG_getEncryptionPublicKey ( ) boxPubKey {
2018-01-04 22:37:51 +00:00
return ( boxPubKey ) ( c . boxPub )
2017-12-29 04:16:20 +00:00
}
2018-01-04 22:37:51 +00:00
func ( c * Core ) DEBUG_getSend ( ) chan <- [ ] byte {
return c . tun . send
2017-12-29 04:16:20 +00:00
}
2018-01-04 22:37:51 +00:00
func ( c * Core ) DEBUG_getRecv ( ) <- chan [ ] byte {
return c . tun . recv
2017-12-29 04:16:20 +00:00
}
// Peer
func ( c * Core ) DEBUG_getPeers ( ) * peers {
2018-01-04 22:37:51 +00:00
return & c . peers
2017-12-29 04:16:20 +00:00
}
2018-06-08 23:42:56 +00:00
func ( ps * peers ) DEBUG_newPeer ( box boxPubKey , sig sigPubKey , link boxSharedKey ) * peer {
2018-01-04 22:37:51 +00:00
//in <-chan []byte,
//out chan<- []byte) *peer {
2018-06-08 23:42:56 +00:00
return ps . newPeer ( & box , & sig , & link ) //, in, out)
2017-12-29 04:16:20 +00:00
}
/ *
func ( ps * peers ) DEBUG_startPeers ( ) {
ps . mutex . RLock ( )
defer ps . mutex . RUnlock ( )
for _ , p := range ps . ports {
if p == nil { continue }
go p . MainLoop ( )
}
}
* /
func ( ps * peers ) DEBUG_hasPeer ( key sigPubKey ) bool {
2018-01-04 22:37:51 +00:00
ports := ps . ports . Load ( ) . ( map [ switchPort ] * peer )
for _ , p := range ports {
if p == nil {
continue
}
if p . sig == key {
return true
}
}
return false
2017-12-29 04:16:20 +00:00
}
func ( ps * peers ) DEBUG_getPorts ( ) map [ switchPort ] * peer {
2018-01-04 22:37:51 +00:00
ports := ps . ports . Load ( ) . ( map [ switchPort ] * peer )
newPeers := make ( map [ switchPort ] * peer )
for port , p := range ports {
newPeers [ port ] = p
}
return newPeers
2017-12-29 04:16:20 +00:00
}
func ( p * peer ) DEBUG_getSigKey ( ) sigPubKey {
2018-01-04 22:37:51 +00:00
return p . sig
2017-12-29 04:16:20 +00:00
}
func ( p * peer ) DEEBUG_getPort ( ) switchPort {
2018-01-04 22:37:51 +00:00
return p . port
2017-12-29 04:16:20 +00:00
}
// Router
func ( c * Core ) DEBUG_getSwitchTable ( ) * switchTable {
2018-01-04 22:37:51 +00:00
return & c . switchTable
2017-12-29 04:16:20 +00:00
}
func ( c * Core ) DEBUG_getLocator ( ) switchLocator {
2018-01-04 22:37:51 +00:00
return c . switchTable . getLocator ( )
2017-12-29 04:16:20 +00:00
}
func ( l * switchLocator ) DEBUG_getCoords ( ) [ ] byte {
2018-01-04 22:37:51 +00:00
return l . getCoords ( )
2017-12-29 04:16:20 +00:00
}
2018-06-08 01:29:22 +00:00
func ( c * Core ) DEBUG_switchLookup ( dest [ ] byte ) switchPort {
2018-06-24 04:55:27 +00:00
return c . switchTable . DEBUG_lookup ( dest )
}
// This does the switch layer lookups that decide how to route traffic.
// Traffic uses greedy routing in a metric space, where the metric distance between nodes is equal to the distance between them on the tree.
// Traffic must be routed to a node that is closer to the destination via the metric space distance.
// In the event that two nodes are equally close, it gets routed to the one with the longest uptime (due to the order that things are iterated over).
// The size of the outgoing packet queue is added to a node's tree distance when the cost of forwarding to a node, subject to the constraint that the real tree distance puts them closer to the destination than ourself.
// Doing so adds a limited form of backpressure routing, based on local information, which allows us to forward traffic around *local* bottlenecks, provided that another greedy path exists.
func ( t * switchTable ) DEBUG_lookup ( dest [ ] byte ) switchPort {
table := t . getTable ( )
myDist := table . self . dist ( dest )
if myDist == 0 {
return 0
}
// cost is in units of (expected distance) + (expected queue size), where expected distance is used as an approximation of the minimum backpressure gradient needed for packets to flow
ports := t . core . peers . getPorts ( )
var best switchPort
bestCost := int64 ( ^ uint64 ( 0 ) >> 1 )
for _ , info := range table . elems {
dist := info . locator . dist ( dest )
if ! ( dist < myDist ) {
continue
}
//p, isIn := ports[info.port]
_ , isIn := ports [ info . port ]
if ! isIn {
continue
}
cost := int64 ( dist ) // + p.getQueueSize()
if cost < bestCost {
best = info . port
bestCost = cost
}
}
return best
2017-12-29 04:16:20 +00:00
}
/ *
func ( t * switchTable ) DEBUG_isDirty ( ) bool {
//data := t.data.Load().(*tabledata)
t . mutex . RLock ( )
defer t . mutex . RUnlock ( )
data := t . data
return data . dirty
}
* /
func ( t * switchTable ) DEBUG_dumpTable ( ) {
2018-01-04 22:37:51 +00:00
//data := t.data.Load().(*tabledata)
t . mutex . RLock ( )
defer t . mutex . RUnlock ( )
data := t . data
for _ , peer := range data . peers {
//fmt.Println("DUMPTABLE:", t.treeID, peer.treeID, peer.port,
// peer.locator.Root, peer.coords,
// peer.reverse.Root, peer.reverse.Coords, peer.forward)
fmt . Println ( "DUMPTABLE:" , t . key , peer . key , peer . locator . coords , peer . port /*, peer.forward*/ )
}
2017-12-29 04:16:20 +00:00
}
func ( t * switchTable ) DEBUG_getReversePort ( port switchPort ) switchPort {
2018-01-04 22:37:51 +00:00
// Returns Port(0) if it cannot get the reverse peer for any reason
//data := t.data.Load().(*tabledata)
t . mutex . RLock ( )
defer t . mutex . RUnlock ( )
data := t . data
if port >= switchPort ( len ( data . peers ) ) {
return switchPort ( 0 )
}
pinfo := data . peers [ port ]
if len ( pinfo . locator . coords ) < 1 {
return switchPort ( 0 )
}
return pinfo . locator . coords [ len ( pinfo . locator . coords ) - 1 ]
2017-12-29 04:16:20 +00:00
}
// Wire
func DEBUG_wire_encode_coords ( coords [ ] byte ) [ ] byte {
2018-01-04 22:37:51 +00:00
return wire_encode_coords ( coords )
2017-12-29 04:16:20 +00:00
}
// DHT, via core
func ( c * Core ) DEBUG_getDHTSize ( ) int {
2018-10-20 20:21:40 +00:00
var total int
c . router . doAdmin ( func ( ) {
total = len ( c . dht . table )
} )
2018-10-20 21:27:01 +00:00
fmt . Println ( "DEBUG_getDHTSize():" , total )
2018-01-04 22:37:51 +00:00
return total
2017-12-29 04:16:20 +00:00
}
2018-03-03 12:30:54 +00:00
// TUN defaults
func ( c * Core ) DEBUG_GetTUNDefaultIfName ( ) string {
2018-07-09 08:38:48 +00:00
return defaults . GetDefaults ( ) . DefaultIfName
2018-03-03 12:30:54 +00:00
}
func ( c * Core ) DEBUG_GetTUNDefaultIfMTU ( ) int {
2018-07-09 08:38:48 +00:00
return defaults . GetDefaults ( ) . DefaultIfMTU
2018-03-03 12:30:54 +00:00
}
func ( c * Core ) DEBUG_GetTUNDefaultIfTAPMode ( ) bool {
2018-07-09 08:38:48 +00:00
return defaults . GetDefaults ( ) . DefaultIfTAPMode
2018-03-03 12:30:54 +00:00
}
2017-12-29 04:16:20 +00:00
// udpInterface
// FIXME udpInterface isn't exported
// So debug functions need to work differently...
/ *
func ( c * Core ) DEBUG_setupLoopbackUDPInterface ( ) {
iface := udpInterface { }
iface . init ( c , "[::1]:0" )
c . ifaces = append ( c . ifaces [ : 0 ] , & iface )
}
* /
/ *
func ( c * Core ) DEBUG_getLoopbackAddr ( ) net . Addr {
iface := c . ifaces [ 0 ]
return iface . sock . LocalAddr ( )
}
* /
/ *
func ( c * Core ) DEBUG_addLoopbackPeer ( addr * net . UDPAddr ,
in ( chan <- [ ] byte ) ,
out ( <- chan [ ] byte ) ) {
iface := c . ifaces [ 0 ]
iface . addPeer ( addr , in , out )
}
* /
/ *
func ( c * Core ) DEBUG_startLoopbackUDPInterface ( ) {
iface := c . ifaces [ 0 ]
go iface . reader ( )
for addr , chs := range iface . peers {
udpAddr , err := net . ResolveUDPAddr ( "udp6" , addr )
if err != nil { panic ( err ) }
go iface . writer ( udpAddr , chs . out )
}
}
* /
////////////////////////////////////////////////////////////////////////////////
func ( c * Core ) DEBUG_getAddr ( ) * address {
2018-01-04 22:37:51 +00:00
return address_addrForNodeID ( & c . dht . nodeID )
2017-12-29 04:16:20 +00:00
}
2018-02-11 21:45:44 +00:00
func ( c * Core ) DEBUG_startTun ( ifname string , iftapmode bool ) {
c . DEBUG_startTunWithMTU ( ifname , iftapmode , 1280 )
2017-12-29 04:16:20 +00:00
}
2018-02-11 21:45:44 +00:00
func ( c * Core ) DEBUG_startTunWithMTU ( ifname string , iftapmode bool , mtu int ) {
2018-01-04 22:37:51 +00:00
addr := c . DEBUG_getAddr ( )
straddr := fmt . Sprintf ( "%s/%v" , net . IP ( addr [ : ] ) . String ( ) , 8 * len ( address_prefix ) )
2018-02-15 22:29:13 +00:00
if ifname != "none" {
err := c . tun . setup ( ifname , iftapmode , straddr , mtu )
if err != nil {
panic ( err )
}
2018-04-28 21:39:58 +00:00
c . log . Println ( "Setup TUN/TAP:" , c . tun . iface . Name ( ) , straddr )
2018-03-03 19:56:26 +00:00
go func ( ) { panic ( c . tun . read ( ) ) } ( )
2018-01-04 22:37:51 +00:00
}
2018-03-03 19:56:26 +00:00
go func ( ) { panic ( c . tun . write ( ) ) } ( )
2017-12-29 04:16:20 +00:00
}
func ( c * Core ) DEBUG_stopTun ( ) {
2018-01-04 22:37:51 +00:00
c . tun . close ( )
2017-12-29 04:16:20 +00:00
}
////////////////////////////////////////////////////////////////////////////////
func ( c * Core ) DEBUG_newBoxKeys ( ) ( * boxPubKey , * boxPrivKey ) {
2018-01-04 22:37:51 +00:00
return newBoxKeys ( )
2017-12-29 04:16:20 +00:00
}
2018-06-08 23:42:56 +00:00
func ( c * Core ) DEBUG_getSharedKey ( myPrivKey * boxPrivKey , othersPubKey * boxPubKey ) * boxSharedKey {
return getSharedKey ( myPrivKey , othersPubKey )
}
2017-12-29 04:16:20 +00:00
func ( c * Core ) DEBUG_newSigKeys ( ) ( * sigPubKey , * sigPrivKey ) {
2018-01-04 22:37:51 +00:00
return newSigKeys ( )
2017-12-29 04:16:20 +00:00
}
func ( c * Core ) DEBUG_getNodeID ( pub * boxPubKey ) * NodeID {
2018-01-04 22:37:51 +00:00
return getNodeID ( pub )
2017-12-29 04:16:20 +00:00
}
func ( c * Core ) DEBUG_getTreeID ( pub * sigPubKey ) * TreeID {
2018-01-04 22:37:51 +00:00
return getTreeID ( pub )
2017-12-29 04:16:20 +00:00
}
func ( c * Core ) DEBUG_addrForNodeID ( nodeID * NodeID ) string {
2018-01-04 22:37:51 +00:00
return net . IP ( address_addrForNodeID ( nodeID ) [ : ] ) . String ( )
2017-12-29 04:16:20 +00:00
}
func ( c * Core ) DEBUG_init ( bpub [ ] byte ,
2018-01-04 22:37:51 +00:00
bpriv [ ] byte ,
spub [ ] byte ,
spriv [ ] byte ) {
var boxPub boxPubKey
var boxPriv boxPrivKey
var sigPub sigPubKey
var sigPriv sigPrivKey
copy ( boxPub [ : ] , bpub )
copy ( boxPriv [ : ] , bpriv )
copy ( sigPub [ : ] , spub )
copy ( sigPriv [ : ] , spriv )
c . init ( & boxPub , & boxPriv , & sigPub , & sigPriv )
2018-05-27 21:13:37 +00:00
if err := c . router . start ( ) ; err != nil {
panic ( err )
}
2017-12-29 04:16:20 +00:00
}
////////////////////////////////////////////////////////////////////////////////
2018-06-06 21:40:35 +00:00
/ *
2017-12-29 04:16:20 +00:00
func ( c * Core ) DEBUG_setupAndStartGlobalUDPInterface ( addrport string ) {
2018-05-27 17:56:33 +00:00
if err := c . udp . init ( c , addrport ) ; err != nil {
c . log . Println ( "Failed to start UDP interface:" , err )
panic ( err )
}
2017-12-29 04:16:20 +00:00
}
2018-01-25 00:45:29 +00:00
func ( c * Core ) DEBUG_getGlobalUDPAddr ( ) * net . UDPAddr {
return c . udp . sock . LocalAddr ( ) . ( * net . UDPAddr )
2017-12-29 04:16:20 +00:00
}
2018-01-03 00:45:09 +00:00
func ( c * Core ) DEBUG_maybeSendUDPKeys ( saddr string ) {
2018-01-13 13:26:26 +00:00
udpAddr , err := net . ResolveUDPAddr ( "udp" , saddr )
if err != nil {
panic ( err )
}
var addr connAddr
addr . fromUDPAddr ( udpAddr )
2018-01-04 22:37:51 +00:00
c . udp . mutex . RLock ( )
2018-01-13 13:26:26 +00:00
_ , isIn := c . udp . conns [ addr ]
2018-01-04 22:37:51 +00:00
c . udp . mutex . RUnlock ( )
if ! isIn {
c . udp . sendKeys ( addr )
}
2017-12-29 04:16:20 +00:00
}
2018-06-06 21:40:35 +00:00
* /
2017-12-29 04:16:20 +00:00
////////////////////////////////////////////////////////////////////////////////
2018-04-26 14:23:21 +00:00
func ( c * Core ) DEBUG_addPeer ( addr string ) {
2018-10-05 18:28:46 +00:00
err := c . admin . addPeer ( addr , "" )
2018-05-05 22:14:03 +00:00
if err != nil {
panic ( err )
2018-04-26 14:23:21 +00:00
}
}
2018-06-14 17:32:18 +00:00
/ *
2018-04-26 14:23:21 +00:00
func ( c * Core ) DEBUG_addSOCKSConn ( socksaddr , peeraddr string ) {
go func ( ) {
dialer , err := proxy . SOCKS5 ( "tcp" , socksaddr , nil , proxy . Direct )
if err == nil {
conn , err := dialer . Dial ( "tcp" , peeraddr )
if err == nil {
c . tcp . callWithConn ( & wrappedConn {
c : conn ,
raddr : & wrappedAddr {
network : "tcp" ,
addr : peeraddr ,
} ,
} )
}
}
} ( )
}
2018-06-14 17:32:18 +00:00
* /
2018-04-26 14:23:21 +00:00
2017-12-29 04:16:20 +00:00
//*
func ( c * Core ) DEBUG_setupAndStartGlobalTCPInterface ( addrport string ) {
2018-08-18 18:24:02 +00:00
if err := c . tcp . init ( c , addrport , 0 ) ; err != nil {
2018-05-27 17:56:33 +00:00
c . log . Println ( "Failed to start TCP interface:" , err )
panic ( err )
}
2017-12-29 04:16:20 +00:00
}
func ( c * Core ) DEBUG_getGlobalTCPAddr ( ) * net . TCPAddr {
2018-01-04 22:37:51 +00:00
return c . tcp . serv . Addr ( ) . ( * net . TCPAddr )
2017-12-29 04:16:20 +00:00
}
func ( c * Core ) DEBUG_addTCPConn ( saddr string ) {
2018-10-05 18:28:46 +00:00
c . tcp . call ( saddr , nil , "" )
2017-12-29 04:16:20 +00:00
}
2018-01-04 22:37:51 +00:00
2017-12-29 04:16:20 +00:00
//*/
/ *
func ( c * Core ) DEBUG_startSelfPeer ( ) {
c . Peers . mutex . RLock ( )
defer c . Peers . mutex . RUnlock ( )
p := c . Peers . ports [ 0 ]
go p . MainLoop ( )
}
* /
////////////////////////////////////////////////////////////////////////////////
/ *
func ( c * Core ) DEBUG_setupAndStartGlobalKCPInterface ( addrport string ) {
iface := kcpInterface { }
iface . init ( c , addrport )
c . kcp = & iface
}
func ( c * Core ) DEBUG_getGlobalKCPAddr ( ) net . Addr {
return c . kcp . serv . Addr ( )
}
func ( c * Core ) DEBUG_addKCPConn ( saddr string ) {
c . kcp . call ( saddr )
}
* /
////////////////////////////////////////////////////////////////////////////////
2018-01-21 00:17:15 +00:00
func ( c * Core ) DEBUG_setupAndStartAdminInterface ( addrport string ) {
a := admin { }
a . init ( c , addrport )
c . admin = a
}
2018-05-23 10:13:53 +00:00
func ( c * Core ) DEBUG_setupAndStartMulticastInterface ( ) {
m := multicast { }
m . init ( c )
c . multicast = m
2018-05-23 11:04:27 +00:00
m . start ( )
2018-05-23 10:13:53 +00:00
}
2018-01-21 00:17:15 +00:00
////////////////////////////////////////////////////////////////////////////////
2017-12-29 04:16:20 +00:00
func ( c * Core ) DEBUG_setLogger ( log * log . Logger ) {
2018-01-04 22:37:51 +00:00
c . log = log
2017-12-29 04:16:20 +00:00
}
2018-01-09 08:08:54 +00:00
func ( c * Core ) DEBUG_setIfceExpr ( expr * regexp . Regexp ) {
2018-05-23 10:13:53 +00:00
c . ifceExpr = append ( c . ifceExpr , expr )
2018-01-09 08:08:54 +00:00
}
2018-05-23 10:28:20 +00:00
func ( c * Core ) DEBUG_addAllowedEncryptionPublicKey ( boxStr string ) {
err := c . admin . addAllowedEncryptionPublicKey ( boxStr )
2018-05-07 00:48:26 +00:00
if err != nil {
panic ( err )
}
2018-05-06 21:32:34 +00:00
}
2017-12-29 04:16:20 +00:00
////////////////////////////////////////////////////////////////////////////////
func DEBUG_simLinkPeers ( p , q * peer ) {
2018-01-04 22:37:51 +00:00
// Sets q.out() to point to p and starts p.linkLoop()
2018-06-07 05:49:06 +00:00
p . linkOut , q . linkOut = make ( chan [ ] byte , 1 ) , make ( chan [ ] byte , 1 )
go func ( ) {
for bs := range p . linkOut {
q . handlePacket ( bs )
}
} ( )
go func ( ) {
for bs := range q . linkOut {
p . handlePacket ( bs )
}
} ( )
2018-01-04 22:37:51 +00:00
p . out = func ( bs [ ] byte ) {
2018-06-24 02:51:32 +00:00
p . core . switchTable . idleIn <- p . port
2018-06-06 22:44:10 +00:00
go q . handlePacket ( bs )
2018-01-04 22:37:51 +00:00
}
q . out = func ( bs [ ] byte ) {
2018-06-24 02:51:32 +00:00
q . core . switchTable . idleIn <- q . port
2018-06-06 22:44:10 +00:00
go p . handlePacket ( bs )
2018-01-04 22:37:51 +00:00
}
2018-06-06 22:44:10 +00:00
go p . linkLoop ( )
go q . linkLoop ( )
2018-06-24 02:51:32 +00:00
p . core . switchTable . idleIn <- p . port
q . core . switchTable . idleIn <- q . port
2017-12-29 04:16:20 +00:00
}
2018-02-17 23:10:08 +00:00
func ( c * Core ) DEBUG_simFixMTU ( ) {
c . tun . mtu = 65535
}
2018-05-27 22:31:34 +00:00
////////////////////////////////////////////////////////////////////////////////
func Util_testAddrIDMask ( ) {
for idx := 0 ; idx < 16 ; idx ++ {
var orig NodeID
orig [ 8 ] = 42
for bidx := 0 ; bidx < idx ; bidx ++ {
orig [ bidx / 8 ] |= ( 0x80 >> uint8 ( bidx % 8 ) )
}
addr := address_addrForNodeID ( & orig )
nid , mask := addr . getNodeIDandMask ( )
for b := 0 ; b < len ( mask ) ; b ++ {
nid [ b ] &= mask [ b ]
orig [ b ] &= mask [ b ]
}
if * nid != orig {
fmt . Println ( orig )
fmt . Println ( * addr )
fmt . Println ( * nid )
fmt . Println ( * mask )
panic ( idx )
}
}
}