github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/qln/netio.go (about) 1 package qln 2 3 import ( 4 "fmt" 5 "github.com/mit-dci/lit/crypto/koblitz" 6 "github.com/mit-dci/lit/lncore" 7 "github.com/mit-dci/lit/lnutil" 8 "github.com/mit-dci/lit/logging" 9 "strings" 10 ) 11 12 // GetLisAddressAndPorts . 13 // Gets the list of ports where LitNode is listening for incoming connections, 14 // & the connection key 15 func (nd *LitNode) GetLisAddressAndPorts() (string, []string) { 16 return nd.PeerMan.GetExternalAddress(), nd.PeerMan.GetListeningAddrs() 17 } 18 19 // FindPeerIndexByAddress finds the peer index by address. 20 // TODO Remove this function. 21 func (nd *LitNode) FindPeerIndexByAddress(lnAdr string) (uint32, error) { 22 pm := nd.PeerMan 23 lnaddr, err := lncore.ParseLnAddr(lnAdr) 24 if err != nil { 25 return 0, err 26 } 27 28 p := pm.GetPeer(lnaddr) 29 if p != nil { 30 return p.GetIdx(), nil 31 } 32 33 return 0, fmt.Errorf("Node %s not found", lnAdr) 34 } 35 36 // TCPListener starts a litNode listening for incoming LNDC connections. 37 func (nd *LitNode) TCPListener(port int) (string, error) { 38 39 logging.Debugf("Trying to listen on %s\n", port) 40 41 err := nd.PeerMan.ListenOnPort(port) 42 if err != nil { 43 return "", err 44 } 45 46 lnaddr := nd.PeerMan.GetExternalAddress() 47 48 logging.Infof("Listening with ln address: %s \n", lnaddr) 49 50 // Don't announce on the tracker if we are communicating via SOCKS proxy 51 if nd.ProxyURL == "" { 52 go GoAnnounce(nd.IdKey(), port, lnaddr, nd.TrackerURL) 53 } 54 55 return lnaddr, nil 56 57 } 58 59 func GoAnnounce(priv *koblitz.PrivateKey, port int, litadr string, trackerURL string) { 60 err := lnutil.Announce(priv, port, litadr, trackerURL) 61 if err != nil { 62 logging.Errorf("Announcement error %s", err.Error()) 63 } 64 } 65 66 // ParseAdrString splits a string like 67 // "ln1yrvw48uc3atg8e2lzs43mh74m39vl785g4ehem@myhost.co:8191" into a separate 68 // pkh part and network part, adding the network part if needed 69 func splitAdrString(adr string) (string, string) { 70 71 if !strings.ContainsRune(adr, ':') && strings.ContainsRune(adr, '@') { 72 adr += ":2448" 73 } 74 75 idHost := strings.Split(adr, "@") 76 77 if len(idHost) == 1 { 78 return idHost[0], "" 79 } 80 81 return idHost[0], idHost[1] 82 } 83 84 // DialPeer makes an outgoing connection to another node. 85 // TODO Remove this. 86 func (nd *LitNode) DialPeer(connectAdr string) error { 87 88 _, err := nd.PeerMan.TryConnectAddress(connectAdr) 89 if err != nil { 90 return err 91 } 92 93 // TEMP The event handler handles actually setting up the peer in the LitNode 94 95 return nil 96 } 97 98 func (nd *LitNode) tmpSendLitMsg(msg lnutil.LitMsg) { 99 100 if !nd.ConnectedToPeer(msg.Peer()) { 101 logging.Debugf("message type %x to peer %d but not connected\n", 102 msg.MsgType(), msg.Peer()) 103 return 104 } 105 106 buf := msg.Bytes() 107 108 // Just wrap it and forward it off to the underlying infrastructure. 109 // There's some byte fenagling that we have to do to get all this to work right. 110 np := nd.PeerMan.GetPeerByIdx(int32(msg.Peer())) 111 np.SendImmediateMessage(LitMsgWrapperMessage{buf[0], buf[1:]}) // being blocking might not be a huge issue here possibly? 112 113 } 114 115 // SimplePeerInfo . 116 type SimplePeerInfo struct { 117 PeerNumber uint32 118 RemoteHost string 119 Nickname string 120 LitAdr string 121 } 122 123 // GetConnectedPeerList . 124 func (nd *LitNode) GetConnectedPeerList() []SimplePeerInfo { 125 peers := make([]SimplePeerInfo, 0) 126 for k := range nd.PeerMap { 127 spi := SimplePeerInfo{ 128 PeerNumber: nd.PeerMan.GetPeerIdx(k), 129 RemoteHost: k.GetRemoteAddr(), 130 Nickname: k.GetNickname(), 131 LitAdr: string(k.GetLnAddr()), 132 } 133 peers = append(peers, spi) 134 } 135 return peers 136 } 137 138 // ConnectedToPeer checks whether you're connected to a specific peer 139 func (nd *LitNode) ConnectedToPeer(peer uint32) bool { 140 // TODO Upgrade this to the new system. 141 nd.RemoteMtx.Lock() 142 defer nd.RemoteMtx.Unlock() 143 _, ok := nd.RemoteCons[peer] 144 return ok 145 } 146 147 // IdKey returns the identity private key 148 func (nd *LitNode) IdKey() *koblitz.PrivateKey { 149 return nd.IdentityKey 150 } 151 152 // SendChat sends a text string to a peer 153 func (nd *LitNode) SendChat(peer uint32, chat string) error { 154 if !nd.ConnectedToPeer(peer) { 155 return fmt.Errorf("Not connected to peer %d", peer) 156 } 157 158 outMsg := lnutil.NewChatMsg(peer, chat) 159 160 nd.tmpSendLitMsg(outMsg) 161 162 return nil 163 }