first commit

This commit is contained in:
Atakan Özgün
2025-12-04 03:37:47 +03:00
commit 6bb67345b8
3 changed files with 646 additions and 0 deletions

144
main.go Normal file
View File

@@ -0,0 +1,144 @@
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()
}
}