exec('SET search_path TO admin, public'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { echo json_encode(['error' => 'DB: ' . $e->getMessage()]); exit; } $input = json_decode(file_get_contents('php://input'), true) ?: $_REQUEST; $action = $input['action'] ?? $_GET['action'] ?? 'status'; switch ($action) { case 'proxies': $country = $input['country'] ?? $_GET['country'] ?? null; $q = "SELECT * FROM edge_proxies WHERE status = 'active'"; if ($country) $q .= " AND country = '" . substr($country, 0, 5) . "'"; $q .= " ORDER BY success_rate DESC, latency_ms ASC"; $proxies = $pdo->query($q)->fetchAll(PDO::FETCH_ASSOC); echo json_encode(['proxies' => $proxies, 'count' => count($proxies)]); break; case 'add_proxy': $ip = $input['ip'] ?? ''; $port = $input['port'] ?? 1080; $country = $input['country'] ?? 'FR'; $city = $input['city'] ?? ''; $ispName = $input['isp_name'] ?? ''; $type = $input['proxy_type'] ?? 'residential'; if (empty($ip)) { echo json_encode(['error' => 'IP required']); exit; } $pdo->prepare("INSERT INTO edge_proxies (ip,port,country,city,isp_name,proxy_type) VALUES (?,?,?,?,?,?)") ->execute([$ip, $port, $country, $city, $ispName, $type]); echo json_encode(['success' => true, 'id' => $pdo->lastInsertId()]); break; case 'test_proxy': $proxyId = $input['proxy_id'] ?? $_GET['id'] ?? 0; $stmt = $pdo->prepare("SELECT * FROM edge_proxies WHERE id = ?"); $stmt->execute([$proxyId]); $proxy = $stmt->fetch(PDO::FETCH_ASSOC); if (!$proxy) { echo json_encode(['error' => 'Proxy not found']); exit; } $start = microtime(true); $ok = false; $extIp = ''; // Test SOCKS5 connectivity $ctx = stream_context_create(['socket' => ['bindto' => '0:0']]); $sock = @fsockopen($proxy['ip'], $proxy['port'], $errno, $errstr, 3); if ($sock) { $latency = round((microtime(true) - $start) * 1000); $ok = true; fclose($sock); } else { $latency = -1; } $pdo->prepare("UPDATE edge_proxies SET latency_ms = ?, last_check = NOW(), status = ? WHERE id = ?") ->execute([$latency, $ok ? 'active' : 'down', $proxyId]); echo json_encode(['proxy_id' => $proxyId, 'ip' => $proxy['ip'], 'reachable' => $ok, 'latency_ms' => $latency, 'isp' => $proxy['isp_name']]); break; case 'route': $targetIsp = $input['target_isp'] ?? 'Gmail'; $country = $input['country'] ?? 'FR'; // Pick best proxy for this ISP+country $stmt = $pdo->prepare("SELECT * FROM edge_proxies WHERE country = ? AND status = 'active' ORDER BY success_rate DESC, latency_ms ASC LIMIT 1"); $stmt->execute([$country]); $proxy = $stmt->fetch(PDO::FETCH_ASSOC); if ($proxy) { $pdo->prepare("INSERT INTO edge_routing_log (proxy_id, target_isp, routed_via, result) VALUES (?,?,?,?)") ->execute([$proxy['id'], $targetIsp, $proxy['isp_name'] . ' ' . $proxy['city'], 'routed']); echo json_encode(['routed' => true, 'proxy' => $proxy['isp_name'], 'city' => $proxy['city'], 'country' => $proxy['country']]); } else { echo json_encode(['routed' => false, 'fallback' => 'direct', 'reason' => 'No residential proxy available for ' . $country]); } break; case 'stats': $proxies = $pdo->query("SELECT COUNT(*) as total, COUNT(*) FILTER (WHERE status='active') as active, COUNT(DISTINCT country) as countries, COUNT(DISTINCT isp_name) as isps, ROUND(AVG(success_rate),1) as avg_success, ROUND(AVG(CASE WHEN latency_ms > 0 THEN latency_ms END),0) as avg_latency FROM edge_proxies")->fetch(PDO::FETCH_ASSOC); $byCountry = $pdo->query("SELECT country, COUNT(*) as cnt, ROUND(AVG(success_rate),1) as avg_success FROM edge_proxies WHERE status='active' GROUP BY country ORDER BY cnt DESC")->fetchAll(PDO::FETCH_ASSOC); $routing = $pdo->query("SELECT COUNT(*) as total_routes, COUNT(*) FILTER (WHERE created_at >= CURRENT_DATE) as today FROM edge_routing_log")->fetch(PDO::FETCH_ASSOC); echo json_encode(['proxies' => $proxies, 'by_country' => $byCountry, 'routing' => $routing]); break; case 'providers': echo json_encode(['providers' => [ ['name' => 'BrightData', 'type' => 'Residential', 'pool' => '72M IPs', 'pricing' => '$8.4/GB', 'status' => 'available'], ['name' => 'Oxylabs', 'type' => 'Residential', 'pool' => '100M IPs', 'pricing' => '$10/GB', 'status' => 'available'], ['name' => 'SmartProxy', 'type' => 'Residential', 'pool' => '55M IPs', 'pricing' => '$7/GB', 'status' => 'available'], ['name' => 'SOAX', 'type' => 'Mobile+Residential', 'pool' => '8.5M IPs', 'pricing' => '$6.6/GB', 'status' => 'available'], ['name' => 'Custom P2P', 'type' => 'Self-hosted mesh', 'pool' => 'TBD', 'pricing' => 'Free', 'status' => 'planned'] ]]); break; default: echo json_encode(['status' => 'online', 'service' => 'Edge Routing Mesh', 'version' => '1.0', 'actions' => ['proxies','add_proxy','test_proxy','route','stats','providers']]); }