#include "istakip_ag.hpp" #include namespace fiko { bool istakipAdresCoz(const std::string& adres, std::string& ip, uint16_t& port, uint16_t varsayilanPort) { if (adres.empty()) return false; const size_t iki = adres.rfind(':'); if (iki == std::string::npos) { ip = adres; port = varsayilanPort; return !ip.empty(); } ip = adres.substr(0, iki); const std::string p = adres.substr(iki + 1); if (ip.empty() || p.empty()) return false; unsigned long v = 0; for (char ch : p) { if (ch < '0' || ch > '9') return false; v = v * 10 + (unsigned long)(ch - '0'); if (v > 65535) return false; } if (v == 0) return false; port = (uint16_t)v; return true; } // ── Kral ───────────────────────────────────────────────────────────────────── bool IstakipTasimaKral::ac(uint16_t port, size_t maksGovde, size_t maksBaglanti) { maksGovde_ = maksGovde; maksBaglanti_ = maksBaglanti ? maksBaglanti : 1; return dinleyici_.ac(port); } void IstakipTasimaKral::kapat() { kanallar_.clear(); dinleyici_.kapat(); } void IstakipTasimaKral::tik() { // Yeni bağlantılar (tek tikte hepsi; kabulEt 0 dönene dek). for (uintptr_t s = dinleyici_.kabulEt(); s; s = dinleyici_.kabulEt()) { if (kanallar_.size() >= maksBaglanti_) { TcpBaglantiWin{s}; // sahiplen + hemen kapat (tavana dayandık) ++reddedilen_; continue; } kanallar_.push_back(std::make_unique(++sonKimlik_, s, maksGovde_)); } // Gelen baytlar → çerçeveler; kopan/bozuk kanal düşer. for (size_t i = 0; i < kanallar_.size();) { Kanal& k = *kanallar_[i]; bool dustu = false; std::string veri; for (int n = k.baglanti.al(veri); n != 0; n = k.baglanti.al(veri)) { if (n < 0) { dustu = true; break; } std::vector gelen; if (!k.cozucu.besle(veri.data(), veri.size(), gelen)) { dustu = true; break; } alinanCerceve_ += gelen.size(); if (alici_) { const orkestra::NodeAdres kaynak{k.kimlik, 0}; for (const auto& c : gelen) alici_(kaynak, c); } veri.clear(); } if (dustu) { const orkestra::NodeAdres adres{k.kimlik, 0}; kanallar_.erase(kanallar_.begin() + (long long)i); if (kopma_) kopma_(adres); } else { ++i; } } } bool IstakipTasimaKral::gonder(const orkestra::NodeAdres& hedef, const SurecCerceve& c) { for (auto& k : kanallar_) if (k->kimlik == hedef.nodeId) return k->baglanti.gonder(surecproto::cerceveSerialize(c)); return false; } // ── İstemci ────────────────────────────────────────────────────────────────── void IstakipTasimaIstemci::hedefAyarla(const std::string& ip, uint16_t port, size_t maksGovde) { ip_ = ip; port_ = port; maksGovde_ = maksGovde; cozucu_ = orkestra::AkisCozucu(maksGovde); sonDenemeMs_ = 0; // ilk tik hemen dener } void IstakipTasimaIstemci::kapat() { baglanti_.kapat(); cozucu_.sifirla(); } void IstakipTasimaIstemci::dus() { baglanti_.kapat(); cozucu_.sifirla(); if (koptu_) koptu_(); } void IstakipTasimaIstemci::tik(uint64_t simdiMs, uint64_t denemeAralikMs) { if (ip_.empty() || port_ == 0) return; if (!baglanti_.acikMi()) { if (simdiMs - sonDenemeMs_ < denemeAralikMs && sonDenemeMs_ != 0) return; sonDenemeMs_ = simdiMs; if (!baglanti_.baglan(ip_.c_str(), port_)) return; cozucu_.sifirla(); if (baglandi_) baglandi_(); } std::string veri; for (int n = baglanti_.al(veri); n != 0; n = baglanti_.al(veri)) { if (n < 0) { dus(); return; } std::vector gelen; if (!cozucu_.besle(veri.data(), veri.size(), gelen)) { dus(); return; } alinanCerceve_ += gelen.size(); if (alici_) { const orkestra::NodeAdres kaynak{0, 0}; // tek karşı uç = kral for (const auto& c : gelen) alici_(kaynak, c); } veri.clear(); } } bool IstakipTasimaIstemci::gonder(const orkestra::NodeAdres& /*hedef*/, const SurecCerceve& c) { if (!baglanti_.acikMi()) return false; if (baglanti_.gonder(surecproto::cerceveSerialize(c))) return true; dus(); // yazım düştü = bağlantı öldü (yeniden bağlanma tik'te) return false; } } // namespace fiko