feat: integración completa de red P2P

- connection.zig: Reescrito con integración completa
  - NAT traversal (STUN + NAT-PMP/UPnP)
  - Discovery (local UDP + global HTTPS)
  - TCP listener para conexiones entrantes
  - Flujo completo de conexión: resolving -> connecting -> handshaking -> connected
  - Envío/recepción de mensajes con protocol framing
  - Gestión de direcciones (local, pública, relay)
  - Port mapping automático

- discovery.zig: Añadidos métodos de DiscoveryManager
  - startLocalDiscovery, stopLocalDiscovery
  - addGlobalServer, announceGlobal
  - addKnownPeer

- crypto.zig: Fix u128 cast para shifts > 64 bits
- http.zig: Fix ArrayListUnmanaged API para Zig 0.15.2

Tests: 44 (todos pasando)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
reugenio 2025-12-15 11:04:11 +01:00
parent 256cb53073
commit 414de51120
5 changed files with 851 additions and 48 deletions

View file

@ -85,10 +85,10 @@ zcatp2p/
- [x] Implementación discovery local (UDP broadcast) - [x] Implementación discovery local (UDP broadcast)
- [x] Implementación STUN client - [x] Implementación STUN client
- [x] Implementación relay client - [x] Implementación relay client
- [x] Tests unitarios (41 tests) - [x] Tests unitarios (44 tests)
- [x] Discovery global (HTTPS API) - [x] Discovery global (HTTPS API)
- [x] UPnP/NAT-PMP port mapping - [x] UPnP/NAT-PMP port mapping
- [ ] Integración completa de red - [x] Integración completa de red
## Comandos ## Comandos

File diff suppressed because it is too large Load diff

View file

@ -456,7 +456,7 @@ pub const Poly1305 = struct {
// Convertir a bytes // Convertir a bytes
var result: [16]u8 = undefined; var result: [16]u8 = undefined;
const full = h0 | (h1 << 44) | (h2 << 88); const full: u128 = @as(u128, h0) | (@as(u128, h1) << 44) | (@as(u128, h2) << 88);
std.mem.writeInt(u128, &result, full, .little); std.mem.writeInt(u128, &result, full, .little);
return result; return result;
} }

View file

@ -519,6 +519,39 @@ pub const DiscoveryManager = struct {
) void { ) void {
self.on_device_discovered = cb; self.on_device_discovered = cb;
} }
/// Inicia el discovery local
pub fn startLocalDiscovery(self: *DiscoveryManager, port: u16) !void {
self.local.local_port = port;
try self.local.start();
}
/// Detiene el discovery local
pub fn stopLocalDiscovery(self: *DiscoveryManager) void {
if (self.local.socket) |sock| {
std.posix.close(sock);
self.local.socket = null;
}
}
/// Añade un servidor de discovery global
pub fn addGlobalServer(self: *DiscoveryManager, server: []const u8) !void {
try self.global.addServer(server);
}
/// Anuncia direcciones en discovery global
pub fn announceGlobal(self: *DiscoveryManager, addresses: []const []const u8) !void {
try self.global.announce(addresses);
}
/// Añade direcciones conocidas para un peer
pub fn addKnownPeer(self: *DiscoveryManager, device_id: DeviceId, addresses: []const []const u8) !void {
// Añadir al cache local
_ = device_id;
for (addresses) |addr| {
try self.local.addAddress(addr);
}
}
}; };
// ============================================================================= // =============================================================================

View file

@ -470,14 +470,15 @@ pub const HttpClient = struct {
response.status_code = @enumFromInt(status_code); response.status_code = @enumFromInt(status_code);
// Status text // Status text
var status_text_parts = std.ArrayList(u8).init(self.allocator); var status_text_parts: std.ArrayListUnmanaged(u8) = .{};
defer status_text_parts.deinit(self.allocator);
while (parts.next()) |part| { while (parts.next()) |part| {
if (status_text_parts.items.len > 0) { if (status_text_parts.items.len > 0) {
try status_text_parts.append(' '); try status_text_parts.append(self.allocator, ' ');
} }
try status_text_parts.appendSlice(part); try status_text_parts.appendSlice(self.allocator, part);
} }
response.status_text = try status_text_parts.toOwnedSlice(); response.status_text = try status_text_parts.toOwnedSlice(self.allocator);
// Parsear headers // Parsear headers
const header_start = status_end + 2; const header_start = status_end + 2;