145 lines
3.7 KiB
Go
145 lines
3.7 KiB
Go
package main
|
||
|
||
import (
|
||
"bufio"
|
||
"context"
|
||
"flag"
|
||
"fmt"
|
||
"log"
|
||
"os"
|
||
"sync"
|
||
"time"
|
||
|
||
"github.com/libp2p/go-libp2p"
|
||
dht "github.com/libp2p/go-libp2p-kad-dht"
|
||
// "github.com/libp2p/go-libp2p/core/host" <-- BU SATIR SİLİNDİ (Hata sebebiydi)
|
||
"github.com/libp2p/go-libp2p/core/network"
|
||
"github.com/libp2p/go-libp2p/core/peer"
|
||
"github.com/libp2p/go-libp2p/p2p/discovery/routing"
|
||
dutil "github.com/libp2p/go-libp2p/p2p/discovery/util"
|
||
)
|
||
|
||
const protocolID = "/onion-chat/1.0.0"
|
||
|
||
func main() {
|
||
rendezvousString := flag.String("r", "gizli-tunel-sifresi", "Buluşma noktası için gizli kelime")
|
||
flag.Parse()
|
||
|
||
ctx := context.Background()
|
||
|
||
// 1. Libp2p Host'u oluştur (NAT Traversal ve Relay özellikleri açık)
|
||
h, err := libp2p.New(
|
||
libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0", "/ip4/0.0.0.0/udp/0/quic-v1"), // TCP ve QUIC dinle
|
||
libp2p.EnableHolePunching(), // NAT arkasından geçmeyi dene
|
||
libp2p.EnableNATService(),
|
||
libp2p.EnableRelay(), // Relay üzerinden geçmeye izin ver
|
||
)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
fmt.Printf("[*] Düğüm Başladı ID: %s\n", h.ID())
|
||
fmt.Println("[*] Küresel ağa bağlanılıyor (Bootstrapping)... Bu biraz sürebilir.")
|
||
|
||
// 2. DHT (Distributed Hash Table) Başlat
|
||
kademliaDHT, err := dht.New(ctx, h)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
// 3. Bootstrap (Başlangıç) Düğümlerine Bağlan
|
||
if err = kademliaDHT.Bootstrap(ctx); err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
// Halka açık varsayılan IPFS düğümlerine bağlanarak ağa dahil ol
|
||
var wg sync.WaitGroup
|
||
for _, peerAddr := range dht.DefaultBootstrapPeers {
|
||
peerinfo, _ := peer.AddrInfoFromP2pAddr(peerAddr)
|
||
wg.Add(1)
|
||
go func() {
|
||
defer wg.Done()
|
||
if err := h.Connect(ctx, *peerinfo); err != nil {
|
||
// Bazılarına bağlanamamak normaldir
|
||
}
|
||
}()
|
||
}
|
||
wg.Wait()
|
||
fmt.Println("[+] Küresel ağa bağlandık! Şimdi arkadaşın aranıyor...")
|
||
|
||
// 4. Stream Handler (Gelen mesajları karşıla)
|
||
h.SetStreamHandler(protocolID, handleStream)
|
||
|
||
// 5. Discovery (Keşif) Mekanizması
|
||
routingDiscovery := routing.NewRoutingDiscovery(kademliaDHT)
|
||
dutil.Advertise(ctx, routingDiscovery, *rendezvousString)
|
||
fmt.Printf("[*] '%s' frekansında yayın yapılıyor.\n", *rendezvousString)
|
||
|
||
// 6. Arkadaşı Ara ve Bağlan
|
||
go func() {
|
||
for {
|
||
peerChan, err := routingDiscovery.FindPeers(ctx, *rendezvousString)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
|
||
for peer := range peerChan {
|
||
if peer.ID == h.ID() {
|
||
continue // Kendimize bağlanmayalım
|
||
}
|
||
|
||
fmt.Printf("[?] Bulunan Peer: %s. Bağlanılıyor...\n", peer.ID)
|
||
|
||
// Bağlantı dene
|
||
if err := h.Connect(ctx, peer); err != nil {
|
||
// Bağlantı başarısız olabilir, tekrar deneriz
|
||
continue
|
||
}
|
||
|
||
fmt.Printf("[+] BAĞLANTI BAŞARILI! Tünel Kuruldu: %s\n", peer.ID)
|
||
|
||
// Stream aç
|
||
stream, err := h.NewStream(ctx, peer.ID, protocolID)
|
||
if err != nil {
|
||
fmt.Println("Stream hatası:", err)
|
||
continue
|
||
}
|
||
|
||
rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))
|
||
go readData(rw)
|
||
go writeData(rw)
|
||
return // Bir kişi bulduk ve bağlandık, aramayı durdur
|
||
}
|
||
time.Sleep(time.Second * 2) // Kimse yoksa 2 saniye sonra tekrar ara
|
||
}
|
||
}()
|
||
|
||
select {} // Programı açık tut
|
||
}
|
||
|
||
func handleStream(s network.Stream) {
|
||
fmt.Println("\n[!] Biri tünelimize giriş yaptı!")
|
||
rw := bufio.NewReadWriter(bufio.NewReader(s), bufio.NewWriter(s))
|
||
go readData(rw)
|
||
go writeData(rw)
|
||
}
|
||
|
||
func readData(rw *bufio.ReadWriter) {
|
||
for {
|
||
str, err := rw.ReadString('\n')
|
||
if err != nil {
|
||
return
|
||
}
|
||
fmt.Printf("\x1b[32m%s\x1b[0m: %s", "Gelen", str)
|
||
}
|
||
}
|
||
|
||
func writeData(rw *bufio.ReadWriter) {
|
||
stdReader := bufio.NewReader(os.Stdin)
|
||
for {
|
||
fmt.Print("> ")
|
||
sendData, _ := stdReader.ReadString('\n')
|
||
rw.WriteString(sendData)
|
||
rw.Flush()
|
||
}
|
||
} |