Files
p2pNetwork/main.go
Atakan Özgün 6bb67345b8 first commit
2025-12-04 03:37:47 +03:00

144 lines
3.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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ıı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()
}
}