Files
p2pNetwork/main.go
Atakan Özgün e152e6509b change
2025-12-04 04:23:28 +03:00

237 lines
6.1 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 (
"context"
"flag"
"fmt"
"io"
"log"
"net"
"strings"
"sync"
"time"
"github.com/armon/go-socks5"
"github.com/libp2p/go-libp2p"
dht "github.com/libp2p/go-libp2p-kad-dht"
"github.com/libp2p/go-libp2p/core/host" // EKLENDİ
"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"
"github.com/libp2p/go-libp2p/p2p/host/autorelay"
"github.com/multiformats/go-multiaddr"
)
const protocolID = "/onion-proxy/1.0.0"
// IPFS Statik Relay Listesi
var relayNodes = []string{
"/ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
"/ip4/147.75.76.67/tcp/4001/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt",
"/ip4/147.75.109.213/tcp/4001/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
}
func main() {
rendezvousString := flag.String("r", "gizli-tunel-sifresi", "Buluşma noktası için şifre")
proxyPort := flag.String("proxy", "", "Client modu: Yerel SOCKS5 portu (Örn: 1080)")
flag.Parse()
ctx := context.Background()
// 1. Statik Relay Listesini Hazırla
var staticRelays []peer.AddrInfo
for _, s := range relayNodes {
ma, err := multiaddr.NewMultiaddr(s)
if err != nil {
continue
}
ai, err := peer.AddrInfoFromP2pAddr(ma)
if err != nil {
continue
}
staticRelays = append(staticRelays, *ai)
}
// 2. Libp2p Host'u oluştur
h, err := libp2p.New(
libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0", "/ip4/0.0.0.0/udp/0/quic-v1"),
libp2p.EnableHolePunching(),
libp2p.EnableNATService(),
libp2p.EnableRelay(),
libp2p.EnableAutoRelay(autorelay.WithStaticRelays(staticRelays)),
libp2p.ForceReachabilityPrivate(),
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("[*] Düğüm ID: %s\n", h.ID())
fmt.Println("[*] Küresel ağa bağlanılıyor (Bootstrapping)...")
// 3. DHT Başlat
kademliaDHT, err := dht.New(ctx, h, dht.Mode(dht.ModeClient))
if err != nil {
log.Fatal(err)
}
if err = kademliaDHT.Bootstrap(ctx); err != nil {
log.Fatal(err)
}
// 4. Bootstrap
var wg sync.WaitGroup
for _, peerAddr := range dht.DefaultBootstrapPeers {
peerinfo, _ := peer.AddrInfoFromP2pAddr(peerAddr)
wg.Add(1)
go func() {
defer wg.Done()
h.Connect(ctx, *peerinfo)
}()
}
wg.Wait()
fmt.Println("[+] IPFS Ağına Bağlanıldı.")
// 5. Relay Bekleme
fmt.Print("[*] Relay bekleniyor...")
for {
hasRelay := false
for _, addr := range h.Addrs() {
if strings.Contains(addr.String(), "p2p-circuit") {
hasRelay = true
break
}
}
if hasRelay {
fmt.Println("\n[+] Relay Tüneli Hazır!")
break
}
fmt.Print(".")
time.Sleep(time.Second * 1)
}
// ==========================================
// SERVER (EXIT NODE) MANTIĞI
// ==========================================
socksConf := &socks5.Config{}
socksServer, err := socks5.New(socksConf)
if err != nil {
panic(err)
}
h.SetStreamHandler(protocolID, func(s network.Stream) {
fmt.Println("\n[->] Tünelden yeni bir internet isteği geldi!")
// HATA ÇÖZÜMÜ 1: Stream'i net.Conn uyumlu hale getiren Wrapper kullanıyoruz
conn := StreamConn{Stream: s}
// Artık socksServer bunu kabul eder
socksServer.ServeConn(conn)
})
// Discovery Başlat
routingDiscovery := routing.NewRoutingDiscovery(kademliaDHT)
dutil.Advertise(ctx, routingDiscovery, *rendezvousString)
fmt.Printf("[*] '%s' kanalında dinleniyor.\n", *rendezvousString)
// ==========================================
// CLIENT (KULLANICI) MANTIĞI
// ==========================================
if *proxyPort != "" {
// HATA ÇÖZÜMÜ 2: host.Host tipini doğru gönderiyoruz
go startLocalProxy(ctx, h, routingDiscovery, *rendezvousString, *proxyPort)
}
select {}
}
// startLocalProxy: HATA ÇÖZÜMÜ 3: h değişkeninin tipi 'host.Host' olarak düzeltildi
func startLocalProxy(ctx context.Context, h host.Host, discovery *routing.RoutingDiscovery, rendezvous, port string) {
fmt.Println("------------------------------------------------")
fmt.Printf("[CLIENT MODU] Yerel Proxy Başlatıldı: 127.0.0.1:%s\n", port)
fmt.Println("Tarayıcının SOCKS5 ayarını buraya yönlendir.")
fmt.Println(ıkış Düğümü (Exit Node) aranıyor...")
fmt.Println("------------------------------------------------")
var targetPeer peer.AddrInfo
found := false
// 1. Çıkış Düğümü Bul
for !found {
peerChan, err := discovery.FindPeers(ctx, rendezvous)
if err != nil {
panic(err)
}
for p := range peerChan {
if p.ID == h.ID() { // LocalPeer yerine h.ID() kullandık
continue
}
// HATA ÇÖZÜMÜ 4: DialPeer yerine Connect kullanıyoruz
if err := h.Connect(ctx, p); err == nil {
fmt.Printf("[+] Çıkış Düğümü Bulundu ve Bağlandı: %s\n", p.ID)
targetPeer = p
found = true
break
}
}
if !found {
time.Sleep(time.Second * 1)
}
}
// 2. Yerel TCP Portunu Dinle
listener, err := net.Listen("tcp", ":"+port)
if err != nil {
log.Fatal(err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Println("Accept hatası:", err)
continue
}
go func(browserConn net.Conn) {
defer browserConn.Close()
// HATA ÇÖZÜMÜ 5: Artık h host.Host olduğu için NewStream 3 argümanı kabul eder
stream, err := h.NewStream(ctx, targetPeer.ID, protocolID)
if err != nil {
log.Println("Tünel açma hatası:", err)
return
}
defer stream.Close()
var wg sync.WaitGroup
wg.Add(2)
go func() {
io.Copy(stream, browserConn)
wg.Done()
}()
go func() {
io.Copy(browserConn, stream)
wg.Done()
}()
wg.Wait()
}(conn)
}
}
// ==========================================
// HATA ÇÖZÜMÜ: Wrapper (Kapsayıcı) Struct
// libp2p Stream'ini net.Conn gibi davranmaya zorlar.
// ==========================================
type StreamConn struct {
network.Stream
}
// SOCKS5 kütüphanesi bu metodları arar, biz de sahte/boş cevaplar döneriz.
func (c StreamConn) LocalAddr() net.Addr {
return &net.TCPAddr{IP: net.IPv4zero, Port: 0}
}
func (c StreamConn) RemoteAddr() net.Addr {
return &net.TCPAddr{IP: net.IPv4zero, Port: 0}
}