{"id":24426087,"url":"https://github.com/xaionaro-go/udpclone","last_synced_at":"2025-10-13T04:32:02.369Z","repository":{"id":268180537,"uuid":"903564573","full_name":"xaionaro-go/udpclone","owner":"xaionaro-go","description":"A simple tool to clone (/tee) UDP traffic to multiple destinations.","archived":false,"fork":false,"pushed_at":"2025-01-02T17:10:24.000Z","size":46,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-13T15:43:49.578Z","etag":null,"topics":["clone","multipath","tee","tunnel","udp"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xaionaro-go.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-14T23:28:18.000Z","updated_at":"2025-02-19T23:46:25.000Z","dependencies_parsed_at":"2024-12-15T00:23:29.159Z","dependency_job_id":"cc508570-30ee-45bc-95a1-b03979615932","html_url":"https://github.com/xaionaro-go/udpclone","commit_stats":null,"previous_names":["xaionaro-go/udpclone"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/xaionaro-go/udpclone","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xaionaro-go%2Fudpclone","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xaionaro-go%2Fudpclone/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xaionaro-go%2Fudpclone/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xaionaro-go%2Fudpclone/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xaionaro-go","download_url":"https://codeload.github.com/xaionaro-go/udpclone/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xaionaro-go%2Fudpclone/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279013689,"owners_count":26085390,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clone","multipath","tee","tunnel","udp"],"created_at":"2025-01-20T11:15:34.324Z","updated_at":"2025-10-13T04:32:02.364Z","avatar_url":"https://github.com/xaionaro-go.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# About\n[![License: CC0-1.0](https://img.shields.io/badge/License-CC0%201.0-lightgrey.svg)](http://creativecommons.org/publicdomain/zero/1.0/)\n\n\n`udpclone` just copies a packet and sends it to as may destinations as needed, and it sends back any traffic that was received from any of these destinations.\n\n```mermaid\nflowchart LR\n    client[UDP client]\n    udpclone[udpclone]\n    R0[receiver 1]\n    R1[receiver 2]\n    R2[receiver 3]\n\n    client \u003c--\u003e|UDP packet| udpclone\n\n    udpclone \u003c--\u003e|UDP packet| R0\n    udpclone \u003c--\u003e|UDP packet| R1\n    udpclone \u003c--\u003e|UDP packet| R2\n```\n\nPersonally I used it for OpenVPN:\n```mermaid\nflowchart LR\n    OVPN0[OpenVPN client]\n    OVPN1[OpenVPN server]\n    udpclone[udpclone]\n    OVPN1P{port 5743}\n    OVPN1P0{port 9000}\n    OVPN1P1{port 9001}\n    OVPN1P2{port 9002}\n\n    OVPN0 \u003c--\u003e|UDP packet| udpclone\n\n    udpclone \u003c--\u003e|UDP packet| OVPN1P0\n    udpclone \u003c--\u003e|UDP packet| OVPN1P1\n    udpclone \u003c--\u003e|UDP packet| OVPN1P2\n\n    OVPN1P0 \u003c--\u003e|REDIRECTed by netfilter| OVPN1P\n    OVPN1P1 \u003c--\u003e|REDIRECTed by netfilter| OVPN1P\n    OVPN1P2 \u003c--\u003e|REDIRECTed by netfilter| OVPN1P\n    OVPN1P \u003c--\u003e|UDP packet| OVPN1\n```\nwhere each connection used different channel via iproute2 rules. OpenVPN drops duplicated packets by itself as part of anti-replay protections.\n\nThis helped to mitigate really poor connection of one of my mobile streaming (SRT) setups, that uses 3 SIM cards. I guess I could've duplicated the traffic of SRT itself instead of OpenVPN, but I also wanted to have SSH and other connections work reliably.\n\n# Howto\n\n### Build\n```sh\ngit clone https://github.com/xaionaro-go/udpclone /opt/udpclone\ncd /opt/udpclone\ngo build\nln -s ../../../opt/udpclone /usr/local/bin\n```\n\n### Run\nConfigure buffers:\n```sh\n# increase the buffer, otherwise we get error \"No buffer space available\"\necho $[ 64 * 1024 * 1024 ] \u003e /proc/sys/net/core/wmem_max\n```\n\nRun `udpclone`:\n```sh\nudpclone --listen-addr 0.0.0.0:9000 --destinations X.X.X.X:9000,Y.Y.Y.Y:9000,Z.Z.Z.Z:9000\n```\n\n# Example\n### The OpenVPN example from \"About\":\n\nClient-side configuration:\n```sh\necho $[ 64 * 1024 * 1024 ] \u003e /proc/sys/net/core/wmem_max # otherwise we get error \"No buffer space available\"\n\nip rule add ipproto udp dport 9000 lookup wlan0  pref 4000\nip rule add ipproto udp dport 9001 lookup rmnet1 pref 4010\nip rule add ipproto udp dport 9002 lookup bt-pan pref 4020\n```\n\n`udpclone` (launched on the client side):\n```\nudpclone --listen-addr 0.0.0.0:5743 --destinations my.home.address:9000,my.home.address:9001,my.home.address:9002\n```\n\nIn my case `my.home.address` was a DyDNS-address.\n\n\nServer-side configuration:\n```sh\nnft add rule nat PREROUTING iif lxc udp dport 9000-9010 ip daddr X.X.X.X dnat X.X.X.X:5743\n```\n\n# Similar projects (and the difference)\n*(feel free to make a PR adding your project here...)*\n* https://github.com/chenx-dust/paracat. deduplicates traffic automatically, by adding a sequence number to packets and then stripping it back. Supports also Round-Robin mode. *But it does not support the case if one of the destinations not available in the beginning or the case of changing the destination IP (a-la DyDNS destinations).*\n* https://github.com/path-network/UDP-Clone. A minimalistic tool that does essentially the same as `udpclone`. *But it does not support the case if one of the destinations not available in the beginning or the case of changing the destination IP (a-la DyDNS destinations).*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxaionaro-go%2Fudpclone","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxaionaro-go%2Fudpclone","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxaionaro-go%2Fudpclone/lists"}