mirror of
https://github.com/PeernetOfficial/Cmd.git
synced 2026-07-17 02:47:52 +01:00
Initial command line client.
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
*.exe
|
||||
log.txt
|
||||
*debug_bin
|
||||
*.yaml
|
||||
201
Command Line.go
Normal file
201
Command Line.go
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
File Name: Command Line.go
|
||||
Copyright: 2021 Peernet Foundation s.r.o.
|
||||
Author: Peter Kleissner
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/PeernetOfficial/core"
|
||||
)
|
||||
|
||||
func getUserOptionString(reader *bufio.Reader) (response string, valid bool) {
|
||||
responseA, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
|
||||
responseA = strings.TrimSpace(responseA) // also removes the delimiter
|
||||
|
||||
return responseA, true
|
||||
}
|
||||
|
||||
func getUserOptionBool(reader *bufio.Reader) (response bool, valid bool) {
|
||||
responseA, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return false, false
|
||||
}
|
||||
|
||||
responseA = strings.TrimSpace(responseA) // also removes the delimiter
|
||||
|
||||
responseI, err := strconv.Atoi(responseA)
|
||||
if err != nil || (responseI != 0 && responseI != 1) {
|
||||
return false, false
|
||||
}
|
||||
|
||||
return responseI == 1, true
|
||||
}
|
||||
|
||||
func getUserOptionInt(reader *bufio.Reader) (response int, valid bool) {
|
||||
responseA, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
responseA = strings.TrimSpace(responseA) // also removes the delimiter
|
||||
|
||||
responseI, err := strconv.Atoi(responseA)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return responseI, true
|
||||
}
|
||||
|
||||
func showHelp() {
|
||||
fmt.Print("Please enter a command:\n")
|
||||
fmt.Print("help Show this help\n" +
|
||||
"net list Lists all network adapters and their IPs\n" +
|
||||
"status Get current status\n" +
|
||||
"chat Send text to all peers\n" +
|
||||
"peer list List current peers\n" +
|
||||
"debug key create Create Public-Private Key pair\n" +
|
||||
"debug key self List current Public-Private Key pair\n" +
|
||||
"\n")
|
||||
}
|
||||
|
||||
func userCommands() {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
fmt.Print("Peernet Cmd " + core.Version + "\n------------------------------\n")
|
||||
showHelp()
|
||||
|
||||
for {
|
||||
command, valid := getUserOptionString(reader)
|
||||
if !valid {
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
switch command {
|
||||
case "help", "?":
|
||||
showHelp()
|
||||
|
||||
case "net list":
|
||||
fmt.Print(NetworkListOutput())
|
||||
|
||||
case "debug key create":
|
||||
privateKey, publicKey, err := core.Secp256k1NewPrivateKey()
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Private Key: %s\n", hex.EncodeToString(privateKey.Serialize()))
|
||||
fmt.Printf("Public Key: %s\n", hex.EncodeToString(publicKey.SerializeCompressed()))
|
||||
|
||||
case "debug key self":
|
||||
privateKey, publicKey := core.ExportPrivateKey()
|
||||
fmt.Printf("Private Key: %s\n", hex.EncodeToString(privateKey.Serialize()))
|
||||
fmt.Printf("Public Key: %s\n", hex.EncodeToString(publicKey.SerializeCompressed()))
|
||||
|
||||
case "peer list":
|
||||
for _, peer := range core.PeerlistGet() {
|
||||
fmt.Printf("* %s\n", hex.EncodeToString(peer.PublicKey.SerializeCompressed()))
|
||||
if len(peer.Connections) > 0 {
|
||||
fmt.Printf(" Connections:\n")
|
||||
for _, connection := range peer.Connections {
|
||||
address, _, _ := connection.Network.GetListen()
|
||||
fmt.Printf(" %-30s on adapter %s\n", connection.Address.String(), address.String())
|
||||
}
|
||||
} else {
|
||||
fmt.Printf(" Connections: [none]\n")
|
||||
}
|
||||
fmt.Printf(" Packets sent: %d\n", peer.StatsPacketSent)
|
||||
fmt.Printf(" Packets received: %d\n", peer.StatsPacketReceived)
|
||||
}
|
||||
|
||||
case "chat all", "chat":
|
||||
if text, valid := getUserOptionString(reader); valid {
|
||||
core.SendChatAll(text)
|
||||
}
|
||||
|
||||
case "status":
|
||||
_, publicKey := core.ExportPrivateKey()
|
||||
fmt.Printf("----------------\nPublic Key: %s\n\n", hex.EncodeToString(publicKey.SerializeCompressed()))
|
||||
|
||||
fmt.Printf("Listen Address Multicast IP out\n")
|
||||
|
||||
for _, network := range core.GetNetworks(4) {
|
||||
address, _, broadcastIPv4 := network.GetListen()
|
||||
fmt.Printf("%-30s\n", address.String())
|
||||
|
||||
for _, broadcastIP := range broadcastIPv4 {
|
||||
fmt.Printf(" %-30s\n", broadcastIP.String())
|
||||
}
|
||||
}
|
||||
for _, network := range core.GetNetworks(6) {
|
||||
address, multicastIP, _ := network.GetListen()
|
||||
fmt.Printf("%-30s %-30s\n", address.String(), multicastIP.String())
|
||||
}
|
||||
|
||||
fmt.Printf("\nPeer ID IP Sent Received\n")
|
||||
for _, peer := range core.PeerlistGet() {
|
||||
fmt.Printf("%-66s %-30s %-8d %-8d\n", hex.EncodeToString(peer.PublicKey.SerializeCompressed()), peer.Connections[0].Address.String(), peer.StatsPacketSent, peer.StatsPacketReceived)
|
||||
}
|
||||
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NetworkListOutput provides a user friendly output
|
||||
func NetworkListOutput() (text string) {
|
||||
|
||||
interfaceList, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return "Error " + err.Error()
|
||||
}
|
||||
|
||||
// iterate through all interfaces
|
||||
for _, ifaceSingle := range interfaceList {
|
||||
text += "Interface " + ifaceSingle.Name + ":\n"
|
||||
//text += " MAC: " + ifaceSingle.HardwareAddr.String() + "\n"
|
||||
|
||||
addresses, err := ifaceSingle.Addrs()
|
||||
if err != nil {
|
||||
text += " Error getting addresses: " + err.Error() + "\n\n"
|
||||
continue
|
||||
}
|
||||
|
||||
// iterate through all IPs of the interfaces
|
||||
for _, address := range addresses {
|
||||
text += " IP: " + address.(*net.IPNet).IP.String() + "\n"
|
||||
}
|
||||
|
||||
// Subscribed Multicast IPs of adapters are not really newsworthy
|
||||
//addresses2, err := ifaceSingle.MulticastAddrs()
|
||||
//if err != nil {
|
||||
// text += " Error getting multicast addresses: " + err.Error() + "\n\n"
|
||||
// continue
|
||||
//}
|
||||
|
||||
//for _, address := range addresses2 {
|
||||
// text += " Multicast: " + address.(*net.IPAddr).IP.String() + "\n"
|
||||
//}
|
||||
|
||||
text += "\n"
|
||||
}
|
||||
|
||||
return text
|
||||
}
|
||||
15
Main.go
Normal file
15
Main.go
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
File Name: Main.go
|
||||
Copyright: 2021 Peernet Foundation s.r.o.
|
||||
Author: Peter Kleissner
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import "github.com/PeernetOfficial/core"
|
||||
|
||||
func main() {
|
||||
core.Connect()
|
||||
|
||||
userCommands()
|
||||
}
|
||||
23
README.md
Normal file
23
README.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Peernet Command Line Client
|
||||
|
||||
This is the command line client used for testing, debug and development purposes. It uses the [core library](https://github.com/PeernetOfficial/core). Check the core library for optional settings.
|
||||
|
||||
This client can be used as root peer to help speed up discovery of peers and data.
|
||||
|
||||
## Compile
|
||||
|
||||
First get all the dependencies. Below list contains both dependencies from the core package and this tool.
|
||||
|
||||
```
|
||||
go get -u github.com/PeernetOfficial/core
|
||||
go get -u github.com/gofrs/uuid
|
||||
go get -u github.com/btcsuite/btcd/btcec
|
||||
go get -u github.com/libp2p/go-reuseport
|
||||
go get -u lukechampine.com/blake3
|
||||
```
|
||||
|
||||
To build:
|
||||
|
||||
```
|
||||
go build
|
||||
```
|
||||
111
Test_test.go
Normal file
111
Test_test.go
Normal file
@@ -0,0 +1,111 @@
|
||||
// Random tests for debugging. Not actual functionality tests.
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/PeernetOfficial/core"
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"lukechampine.com/blake3"
|
||||
)
|
||||
|
||||
func TestSignCompact(t *testing.T) {
|
||||
privateKey, publicKey, err := core.Secp256k1NewPrivateKey()
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var compact1 []byte
|
||||
data := []byte{1, 2, 3}
|
||||
|
||||
time1 := time.Now()
|
||||
|
||||
compact1 = make([]byte, 0)
|
||||
compact1, err = btcec.SignCompact(btcec.S256(), privateKey, chainhash.DoubleHashB(data), true)
|
||||
|
||||
timeT := time.Since(time1)
|
||||
fmt.Printf("length %d time %s\n", len(compact1), timeT.String())
|
||||
|
||||
time2 := time.Now()
|
||||
|
||||
key2, _, err := btcec.RecoverCompact(btcec.S256(), compact1, chainhash.DoubleHashB(data))
|
||||
|
||||
timeT2 := time.Since(time2)
|
||||
fmt.Printf("VALID PUBLIC KEY: %t\n", key2.IsEqual(publicKey))
|
||||
fmt.Printf("time %s\n", timeT2.String())
|
||||
}
|
||||
|
||||
func TestEncryption1(t *testing.T) {
|
||||
privateKey, publicKey, err := core.Secp256k1NewPrivateKey()
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
packet1 := packetRaw{Protocol: 0, Command: 1, Payload: []byte{1, 2, 3}}
|
||||
|
||||
raw1, err := packetEncrypt(privateKey, publicKey, &packet1)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
packet1d, _, err := packetDecrypt(raw1, publicKey)
|
||||
if err != nil {
|
||||
fmt.Printf("Error %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%d\n", packet1d.Command)
|
||||
}
|
||||
|
||||
func BenchmarkHash(b *testing.B) {
|
||||
length := 20000
|
||||
|
||||
b.Run("blake3", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(length))
|
||||
buf := make([]byte, length)
|
||||
rand.Read(buf)
|
||||
for i := 0; i < b.N; i++ {
|
||||
blake3.Sum256(buf)
|
||||
}
|
||||
})
|
||||
b.Run("SHA256 double", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(length))
|
||||
buf := make([]byte, length)
|
||||
rand.Read(buf)
|
||||
for i := 0; i < b.N; i++ {
|
||||
chainhash.DoubleHashB(buf)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestEncryption2(t *testing.T) {
|
||||
privateKey, publicKey, err := core.Secp256k1NewPrivateKey()
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
packet1 := packetRaw{Protocol: 0, Command: 0}
|
||||
|
||||
for n := 0; n < 1000; n++ {
|
||||
raw1, err := packetEncrypt(privateKey, publicKey, &packet1)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
packet1d, _, err := packetDecrypt(raw1, publicKey)
|
||||
if err != nil {
|
||||
fmt.Printf("Error %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
fmt.Printf("Command %d payload %v\n", packet1d.Command, packet1d.Payload)
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user