github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/lnutil/tracker.go (about) 1 package lnutil 2 3 import ( 4 "bytes" 5 "crypto/sha256" 6 "encoding/hex" 7 "encoding/json" 8 "errors" 9 "net/http" 10 "net/url" 11 "strconv" 12 "strings" 13 "time" 14 15 "github.com/mit-dci/lit/crypto/koblitz" 16 "github.com/mit-dci/lit/logging" 17 "golang.org/x/net/proxy" 18 ) 19 20 type announcement struct { 21 ipv4 string 22 ipv6 string 23 addr string 24 sig string 25 pbk string 26 } 27 28 type nodeinfo struct { 29 Success bool 30 Node struct { 31 IPv4 string 32 IPv6 string 33 Addr string 34 } 35 } 36 37 func Announce(priv *koblitz.PrivateKey, port int, litadr string, trackerURL string) error { 38 client := &http.Client{ 39 Timeout: time.Second * 4, // 4+4 to accomodate the 10s RPC timeout 40 } 41 strport := ":" + strconv.Itoa(port) 42 resp, err := client.Get("https://ipv4.myexternalip.com/raw") 43 if err != nil { 44 return err 45 } 46 defer resp.Body.Close() 47 48 buf := new(bytes.Buffer) 49 buf.ReadFrom(resp.Body) 50 51 liturlIPv4 := strings.TrimSpace(buf.String()) + strport 52 53 var liturlIPv6 string 54 55 /* TODO: Find a better way to get this information. Their 56 * SSL cert doesn't work for IPv6. 57 */ 58 resp, err = client.Get("http://ipv6.myexternalip.com/raw") 59 if err != nil { 60 logging.Errorf("%v", err) 61 } else { 62 defer resp.Body.Close() 63 buf = new(bytes.Buffer) 64 buf.ReadFrom(resp.Body) 65 liturlIPv6 = strings.TrimSpace(buf.String()) + strport 66 } 67 68 urlBytes := []byte(liturlIPv4 + liturlIPv6) 69 urlHash := sha256.Sum256(urlBytes) 70 urlSig, err := priv.Sign(urlHash[:]) 71 if err != nil { 72 return err 73 } 74 75 var ann announcement 76 77 ann.ipv4 = liturlIPv4 78 ann.ipv6 = liturlIPv6 79 ann.addr = litadr 80 ann.sig = hex.EncodeToString(urlSig.Serialize()) 81 ann.pbk = hex.EncodeToString(priv.PubKey().SerializeCompressed()) 82 83 _, err = http.PostForm(trackerURL+"/announce", 84 url.Values{"ipv4": {ann.ipv4}, 85 "ipv6": {ann.ipv6}, 86 "addr": {ann.addr}, 87 "sig": {ann.sig}, 88 "pbk": {ann.pbk}}) 89 90 if err != nil { 91 return err 92 } 93 94 return nil 95 } 96 97 func Lookup(litadr string, trackerURL string, proxyURL string) (string, string, error) { 98 var client http.Client 99 100 if proxyURL != "" { 101 dialer, err := proxy.SOCKS5("tcp", proxyURL, nil, proxy.Direct) 102 if err != nil { 103 return "", "", err 104 } 105 106 client.Transport = &http.Transport{ 107 Dial: dialer.Dial, 108 } 109 } 110 111 resp, err := client.Get(trackerURL + "/" + litadr) 112 if err != nil { 113 return "", "", err 114 } 115 defer resp.Body.Close() 116 117 decoder := json.NewDecoder(resp.Body) 118 var node nodeinfo 119 err = decoder.Decode(&node) 120 if err != nil { 121 return "", "", err 122 } 123 124 if !node.Success { 125 return "", "", errors.New("Node not found") 126 } 127 128 return node.Node.IPv4, node.Node.IPv6, nil 129 }