144 lines
3.6 KiB
Go
144 lines
3.6 KiB
Go
package main
|
||
|
||
import (
|
||
"bufio"
|
||
"context"
|
||
"crypto/rand"
|
||
"flag"
|
||
"fmt"
|
||
"io"
|
||
"log"
|
||
"os"
|
||
|
||
"github.com/libp2p/go-libp2p"
|
||
"github.com/libp2p/go-libp2p/core/crypto"
|
||
"github.com/libp2p/go-libp2p/core/host"
|
||
"github.com/libp2p/go-libp2p/core/network"
|
||
"github.com/libp2p/go-libp2p/core/peer"
|
||
"github.com/multiformats/go-multiaddr"
|
||
)
|
||
|
||
const protocolID = "/sallik/1.0.0"
|
||
|
||
func main() {
|
||
// CLI argümanlarını al
|
||
listenPort := flag.Int("p", 0, "Dinlenecek port (0 = rastgele)")
|
||
targetPeer := flag.String("d", "", "Bağlanılacak hedef peer adresi (Client modu için)")
|
||
flag.Parse()
|
||
|
||
ctx := context.Background()
|
||
|
||
// 1. Libp2p Host (Düğüm) Oluştur
|
||
h, err := makeHost(*listenPort)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
// Host bilgilerini yazdır
|
||
fmt.Printf("Benim ID'm: %s\n", h.ID())
|
||
for _, addr := range h.Addrs() {
|
||
fmt.Printf("Dinleniyor: %s/p2p/%s\n", addr, h.ID())
|
||
}
|
||
|
||
// 2. Akış (Stream) Handler Belirle
|
||
// Eğer biri bize bağlanırsa bu fonksiyon çalışacak (Relay Modu)
|
||
h.SetStreamHandler(protocolID, handleStream)
|
||
|
||
// 3. Eğer hedef belirtildiyse Client moduna geç ve bağlan
|
||
if *targetPeer != "" {
|
||
runClient(ctx, h, *targetPeer)
|
||
} else {
|
||
// Hedef yoksa sadece Relay olarak bekle
|
||
fmt.Println("\nRelay modu aktif. Bağlantı bekleniyor... (Çıkış için CTRL+C)")
|
||
select {} // Sonsuz döngü
|
||
}
|
||
}
|
||
|
||
// makeHost: Yeni bir libp2p düğümü başlatır
|
||
func makeHost(port int) (host.Host, error) {
|
||
// Kimlik için RSA anahtarı oluştur (Gerçekte bu kaydedilip tekrar yüklenmeli)
|
||
priv, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, rand.Reader)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// Belirtilen portta dinle (0.0.0.0 tüm arayüzler demek)
|
||
sourceMultiAddr, _ := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", port))
|
||
|
||
return libp2p.New(
|
||
libp2p.Identity(priv),
|
||
libp2p.ListenAddrs(sourceMultiAddr),
|
||
)
|
||
}
|
||
|
||
// handleStream: Gelen bağlantıyı karşılar (Server tarafı)
|
||
func handleStream(s network.Stream) {
|
||
fmt.Println("\n[!] Yeni bir tünel bağlantısı kabul edildi!")
|
||
|
||
// Gelen veriyi okumak ve yazmak için tampon (buffer) oluştur
|
||
rw := bufio.NewReadWriter(bufio.NewReader(s), bufio.NewWriter(s))
|
||
|
||
// Basit bir echo/okuma döngüsü
|
||
go readData(rw)
|
||
go writeData(rw) // Sunucu da cevap yazabilsin
|
||
}
|
||
|
||
// runClient: Başka bir düğüme bağlanır (Client tarafı)
|
||
func runClient(ctx context.Context, h host.Host, target string) {
|
||
// Hedef adresi parse et
|
||
maddr, err := multiaddr.NewMultiaddr(target)
|
||
if err != nil {
|
||
log.Fatalln(err)
|
||
}
|
||
|
||
// Adresten PeerID ve IP bilgisini ayır
|
||
info, err := peer.AddrInfoFromP2pAddr(maddr)
|
||
if err != nil {
|
||
log.Fatalln(err)
|
||
}
|
||
|
||
// Hedefe bağlan (Host.Connect)
|
||
if err := h.Connect(ctx, *info); err != nil {
|
||
log.Fatalln("Bağlantı hatası:", err)
|
||
}
|
||
fmt.Println("\n[+] Hedef düğüme başarıyla bağlanıldı!")
|
||
|
||
// Protokol üzerinden bir stream (kanal) aç
|
||
s, err := h.NewStream(ctx, info.ID, protocolID)
|
||
if err != nil {
|
||
log.Fatalln("Stream açma hatası:", err)
|
||
}
|
||
|
||
rw := bufio.NewReadWriter(bufio.NewReader(s), bufio.NewWriter(s))
|
||
|
||
// Veri alışverişini başlat
|
||
go readData(rw)
|
||
go writeData(rw)
|
||
|
||
select {} // Programı açık tut
|
||
}
|
||
|
||
// Okuma Yardımcısı
|
||
func readData(rw *bufio.ReadWriter) {
|
||
for {
|
||
str, err := rw.ReadString('\n')
|
||
if err != nil {
|
||
if err != io.EOF {
|
||
fmt.Println("Okuma hatası:", err)
|
||
}
|
||
return
|
||
}
|
||
fmt.Printf("\x1b[32m%s\x1b[0m: %s", "Gelen Mesaj", str)
|
||
}
|
||
}
|
||
|
||
// Yazma Yardımcısı (Konsoldan girileni karşıya atar)
|
||
func writeData(rw *bufio.ReadWriter) {
|
||
stdReader := bufio.NewReader(os.Stdin)
|
||
for {
|
||
fmt.Print("> ")
|
||
sendData, _ := stdReader.ReadString('\n')
|
||
rw.WriteString(sendData)
|
||
rw.Flush()
|
||
}
|
||
} |