From 5c5ea52deb662ebd9db45496e2685de90c053195 Mon Sep 17 00:00:00 2001 From: Luna Date: Mon, 19 Dec 2022 21:24:55 -0300 Subject: [PATCH] initial coommit --- .gitattributes | 3 +++ .gitignore | 3 +++ LICENSE | 21 +++++++++++++++++ build.zig | 36 +++++++++++++++++++++++++++++ src/main.zig | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ zigmod.lock | 2 ++ zigmod.yml | 6 +++++ 7 files changed, 134 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 build.zig create mode 100644 src/main.zig create mode 100644 zigmod.lock create mode 100644 zigmod.yml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..403c8ef --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +* text=auto +*.zig text eol=lf +zigmod.* text eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7196971 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +zig-* +.zigmod +deps.zig diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..396cd06 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Luna + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..346d8e9 --- /dev/null +++ b/build.zig @@ -0,0 +1,36 @@ +const std = @import("std"); +const deps = @import("deps.zig"); + +pub fn build(b: *std.build.Builder) void { + // Standard target options allows the person running `zig build` to choose + // what target to build for. Here we do not override the defaults, which + // means any target is allowed, and the default is native. Other options + // for restricting supported target set are available. + const target = b.standardTargetOptions(.{}); + + // Standard release options allow the person running `zig build` to select + // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. + const mode = b.standardReleaseOptions(); + + const exe = b.addExecutable("unicorn_screams", "src/main.zig"); + exe.setTarget(target); + exe.setBuildMode(mode); + exe.install(); + deps.addAllTo(exe); + + const run_cmd = exe.run(); + run_cmd.step.dependOn(b.getInstallStep()); + if (b.args) |args| { + run_cmd.addArgs(args); + } + + const run_step = b.step("run", "Run the app"); + run_step.dependOn(&run_cmd.step); + + const exe_tests = b.addTest("src/main.zig"); + exe_tests.setTarget(target); + exe_tests.setBuildMode(mode); + + const test_step = b.step("test", "Run unit tests"); + test_step.dependOn(&exe_tests.step); +} diff --git a/src/main.zig b/src/main.zig new file mode 100644 index 0000000..dd70aef --- /dev/null +++ b/src/main.zig @@ -0,0 +1,63 @@ +const std = @import("std"); +const network = @import("network"); + +const logger = std.log.scoped(.udp2udp2udp); + +fn incomingAddr(args_it: anytype) !network.EndPoint { + const addr_string = args_it.next().?; + const port_string = args_it.next().?; + + const port = try std.fmt.parseInt(u16, port_string, 10); + const zig_addr = try std.net.Address.parseIp(addr_string, port); + + const socklen = zig_addr.getOsSockLen(); + return network.EndPoint.fromSocketAddress(&zig_addr.any, socklen); +} + +const WantedMode = enum { send, recv }; +const AddrTuple = struct { from: network.EndPoint, to: network.EndPoint }; +const Mode = union(enum) { send: AddrTuple, recv: AddrTuple }; + +pub fn main() !void { + try network.init(); + defer network.deinit(); + + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer { + _ = gpa.deinit(); + } + const allocator = gpa.allocator(); + + var args_it = try std.process.argsWithAllocator(allocator); + defer args_it.deinit(); + + _ = args_it.skip(); + + const from = try incomingAddr(&args_it); + const to = try incomingAddr(&args_it); + std.log.info("taking udp from: {s}", .{from}); + std.log.info("spitting udp to: {s}", .{to}); + + logger.info("init udp", .{}); + var from_sock = try network.Socket.create(.ipv4, .udp); + defer from_sock.close(); + try from_sock.enablePortReuse(true); + try from_sock.bind(from); + + var to_sock = try network.Socket.create(.ipv4, .udp); + defer to_sock.close(); + + var receive_buffer: [2048]u8 = undefined; + while (true) { + const reader = from_sock.reader(); + const received_bytes = try reader.read(&receive_buffer); + const bytes = receive_buffer[0..received_bytes]; + const sent_bytes = try to_sock.sendTo(to, bytes); + if (sent_bytes != received_bytes) { + logger.warn( + "tried to send {d} bytes, actually sent {d}", + .{ received_bytes, sent_bytes }, + ); + } + } +} diff --git a/zigmod.lock b/zigmod.lock new file mode 100644 index 0000000..2a228a6 --- /dev/null +++ b/zigmod.lock @@ -0,0 +1,2 @@ +2 +git https://github.com/MasterQ32/zig-network commit-caa31ef8783695f0441b1f6812985e6a46b32c96 diff --git a/zigmod.yml b/zigmod.yml new file mode 100644 index 0000000..d812782 --- /dev/null +++ b/zigmod.yml @@ -0,0 +1,6 @@ +id: jsmj7bl93sbzxlt10ezhp6j2pe24xmotxmeerhoyxtmvsjkk +name: unicorn_screams +license: MIT +description: Relay Scream packets between two UDP addresses +root_dependencies: + - src: git https://github.com/MasterQ32/zig-network