{"id":48521221,"url":"https://github.com/sunipkm/peernet","last_synced_at":"2026-04-07T21:01:42.260Z","repository":{"id":60035337,"uuid":"538718043","full_name":"sunipkm/peernet","owner":"sunipkm","description":"Local network Peer-to-peer library with peer discovery and callback mechanism.","archived":false,"fork":false,"pushed_at":"2022-10-31T20:37:57.000Z","size":162,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-03-10T02:56:17.521Z","etag":null,"topics":["c","localnetwork","networking","p2p","peer-to-peer"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sunipkm.png","metadata":{"files":{"readme":"README.MD","changelog":"CHANGELOG.MD","contributing":null,"funding":null,"license":"license.xml","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-09-19T22:24:04.000Z","updated_at":"2022-09-21T07:23:43.000Z","dependencies_parsed_at":"2023-01-20T16:38:08.969Z","dependency_job_id":null,"html_url":"https://github.com/sunipkm/peernet","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/sunipkm/peernet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunipkm%2Fpeernet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunipkm%2Fpeernet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunipkm%2Fpeernet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunipkm%2Fpeernet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sunipkm","download_url":"https://codeload.github.com/sunipkm/peernet/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunipkm%2Fpeernet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31528751,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"ssl_error","status_checked_at":"2026-04-07T16:28:06.951Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["c","localnetwork","networking","p2p","peer-to-peer"],"created_at":"2026-04-07T21:01:20.004Z","updated_at":"2026-04-07T21:01:42.254Z","avatar_url":"https://github.com/sunipkm.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PeerNet: A cross-platform local-network P2P library\nPeerNet is a wrapper around the [ZeroMQ Zyre](https://github.com/zeromq/zyre) library,\nwith a callback based design that makes application building easy. PeerNet is written\nin C, just like Zyre and [CZMQ](https://github.com/zeromq/czmq) which PeerNet derives\nfrom.\n\nIn PeerNet, a peer can belong to a unique group, and in that group peers can have\nunique names. This allows for message parsing based on which peer it came from,\nunlike Zyre which concerns more with UUIDs which are generated for peers randomly\nat start.\n\nA Python wrapper for PeerNet is also available [here](https://github.com/sunipkm/pypeernet).\n\n## Ownership and License\nPeerNet is developed by Sunip K. Mukherjee. This project uses the MPL v2 license, see LICENSE.\nContributions/ideas are welcome.\n\n## Pre-requisites\nThis version of PeerNet uses mostly Zyre stable API, with the exception of the\n`zyre_set_zcert` draft method from Zyre version 2.0.1. PeerNet will continue to be\ncompatible with Zyre untill this method changes, at which point PeerNet will require\nan update.\nThe exact versions PeerNet was tested against are listed:\n* Zyre 2.0.1 (`git checkout v2.0.1`)\n* CZMQ 4.2.1 (`git checkout v4.2.1`)\n* ZeroMQ 4.3.4 (`git checkout v4.3.4`)\n* libSodium 1.0.18_1 (`git checkout 1.0.18-RELEASE`)\n\nAdditionally, PeerNet requires `cmake` or `autoconf`, `automake` and `libtool` for the build system to work. `pkg-config`, `pcre (libpcre3-dev)` are required for building, alongside Zyre and its pre-requisites.\n\n## Build Process (POSIX)\nCMake is the preferred build tool, as it builds the `chat` example and documentations\nwith ease. To build with CMake, within `peernet` directory, execute:\n\n```\n    $ mkdir build \u0026\u0026 cd build \u0026\u0026 cmake ..\n    $ make\n    $ make test\n    $ sudo make install\n```\n\nThis will build the project and execute the self-test program. Specify `-DCMAKE_INSTALL_PREFIX=/path/to/install` to set a custom installation\nprefix path (hereafter referred to as prefix path). The default prefix path is `/usr/local`.\n\nAlternatively, in the `peernet` directory, execute:\n```\n    $ ./autogen.sh\n    $ ./configure --prefix=\"/path/to/library\"\n    $ make\n    $ make install\n```\n\nCheck out `examples/chat/chat.c` to understand basic usage. The library is also extensively\ndocumented, and a doxygen documentation is generated using the `cmake` build system.\n\nThe PeerNet install prefix path defaults to `/usr/local/` if using the `cmake` build system, or `--prefix` is not supplied in `./configure`.\nThe shared library (`.so` files in Linux and `.dylib` files in macOS) are stored in the `lib` subdirectory under the prefix path.\nMake sure the `lib` directory is exported to the `LD_LIBRARY_PATH` variable so that the shared library can be located by other binaries e.g. the\n`chat` example, or the [pyPeerNet](https://github.com/sunipkm/pypeernet) Python wrapper.\n\n## Installing on Windows\nIt is recommended to use the installer associated with a release. The installer automatically adds the binaries to `PATH` for [pyPeerNet](https://github.com/sunipkm/pypeernet).\n\nAlternatively, obtain the binaries from the zip file included with the latest release and extract the contents. Add `\\path\\to\\\u003cx86|x64\u003e\\bin` to the `PATH` variable.\nReplace `\u003cversion\u003e` with the current `PeerNet` version (e.g. `v3.0.0`), and choose the platform (`x86` or `x64`) accordingly for your system.\nThis step is crucial for [pyPeerNet](https://github.com/sunipkm/pypeernet) to work on Windows.\n\n## The 'Chat' example\nIf built using the `cmake` build system, a `chat.exe` executable is generated in `examples/chat`. To run the program, open a terminal window in the `peernet` directory and run:\n```\n    $ cd examples/chat\n    $ ./chat.exe peer_name\n```\n\nIn order to properly test the program, open another terminal in the `peernet` directory and repeat the steps above. Using the same `peer_name` as the first instance will cause the\nsecond instance to crash. Multiple such instance can be launched in multiple terminal\nwindows, and writing anything in one such terminal, and pressing enter will cause the\ninstance to send the message to all other instances.\n\nThe example starts operation by initializing the peer, and starting it:\n```c\n    peer_t *peer = peer_new(\"peer_name\", NULL, \"password\", true); // creates a peer named \"peer_name\" in the default group with password \"password\" and encryption enabled.\n```\nAt this point, a pre-defined callback function is registered in order to capture any peer that has connected.\n```c\n    peer_on_connect(peer, NULL, \u0026on_connect_callback, NULL); // registers on_connect_callback as a callback for any peer that connects. The callback does not use any local data.\n```\n\nThe `on_connect_callback()` function has the following form:\n```c\n    void on_connect_callback(peer_t *self, const char *message_type, const char *remote_name, void *local_args, void *remote_args, size_t remote_args_len)\n    {\n        peer_on_message(self, remote_name, \"CHAT\", \u0026on_message_callback, NULL);\n    }\n```\nEssentially, the `on_connect` callback that was registered, registers a callback function that is executed when any peer sends a message, of type \"CHAT\", to this peer. The `on_message` callback absolutely requires a peer name in order to avoid message spamming.\n\nThe `on_message_callback()` function has the following form:\n```c\n    void on_connect_callback(peer_t *self, const char *message_type, const char *remote_name, void *local_args, void *remote_args, size_t remote_args_len)\n    {\n        printf(\"%s\u003e %s\\n\", remote_name, (char *) remote_args);\n    }\n```\n\nThe callback will be executed only for a message of type \"CHAT\". Since instances of `chat.exe` are talking amongst one another, the message format sanity is guaranteed.\n\nAt this point, an instance of the peer can be started:\n```c\n    peer_start(peer);\n```\nCZMQ provides a nice variable that can is set when Ctrl + C is pressed (SIGINT is raised),\ncalled `zsys_interrupted`. A `while` loop can be run on this variable after starting the\npeer to monitor input from `stdin`, and `shout` the message to all available `chat.exe` clients:\n```c\n    while (!zsys_interrupted) // run while SIGINT is not raised\n    {\n        char message[1024];\n        if (!fgets (message, 1024, stdin)) // if this returns -1, program was interrupted\n            break;\n        message[strlen (message) - 1] = 0; // Drop the trailing linefeed\n        assert(!peer_shouts(peer, \"CHAT\", \"%s\", message));\n    }\n```\nA peer can be stopped after getting out of the `while` loop by either calling `peer_stop`, or by calling `peer_destroy` which will also free all the resources associated with that instance of peer:\n```c\n    peer_destroy(\u0026peer); // destroy peer\n    return 0;\n```\n\nAll in all, with 36 lines of code, a terminal chat client is implemented.\n\n## Building on Windows\nBuilding `PeerNet` on Windows systems is not straight forward. Use of the attached binaries is suggested.\n\nTo begin with, install Visual Studio Community Edition 2019 with CMake tools.\nAfter the tools are installed, navigate to the `Start Menu`, and find the `Visual Studio 2019` directory sub-menu. Under the sub-menu,\nselect `\u003cx64|x86\u003e Native Tools Command Prompt` depending on your platform (use the cross-compile command tools as needed). \nThis command prompt sets up the build environment with  `cmake`, `cl` (the Visual C++ compiler) etc. Check if you can access \n`git`, `cmake` and `cl` in this command line by typing in the commands one by one. By default, the command line should \nopen to `%USERPROFILE%\\source\\repos` directory. In case it does not, it is recommended that you use the following commands to \ncreate the aforementioned path and work there.\n```cmd\ncd %USERPROFILE%\nmkdir source\ncd source\nmkdir repos\ncd repos\n```\nNote: [Git for Windows](https://git-scm.org) may need to be installed separately prior\nto opening this command line.\n\n### Building Libsodium\nLibsodium is the cryptographic backend that is required. In order to build it:\n```cmd\ngit clone https://github.com/jedisct1/libsodium.git\ncd libsodium\ngit checkout 1.0.18-RELEASE\ncd builds\\msvc\\build\nbuildall.bat\ncd ..\\..\\..\\\n```\nAt this point, the command line should be in the `libsodium` directory. The library files can be found under `bin\\\u003cWin32|x64\u003e\\\u003cDebug|Release\u003e\\\u003cPlatform Toolset\u003e\\\u003cdynamic|ltcg|static\u003e`.\n\nHere, the `\u003cPlatform Toolset\u003e` is the platform toolset you are using: `v100` for `VS2010`, `v140` for `VS2015`, `v141` for `VS2017`, `v142` for `VS2019` etc.\n\nAt this point, in comamnd line:\n```cmd\nstart .\ncd ..\n```\nThis will open a new `File Explorer` window in the `libsodium` directory, and the required build files for `libsodium` can be accessed. The command line is now in the root\ndirectory containing the `libsodium` directory.\n\n### Building ZeroMQ\n```cmd\ngit clone https://github.com/zeromq/libzmq.git\ncd libzmq\ngit checkout v4.3.4\nmkdir build\ncd build\ncmake .. -DBUILD_STATIC=OFF -DBUILD_SHARED=ON -DZMQ_BUILD_TESTS=ON -DWITH_LIBSODIUM=ON -DCMAKE_INCLUDE_PATH=..\\libsodium\\src\\libsodium\\include -DCMAKE_LIBRARY_PATH=..\\libsodium\\bin\\\u003cWin32|x64\u003e\\Release\\\u003cPlatform Toolset\u003e\\dynamic -DCMAKE_INSTALL_PREFIX=C:\\libzmq\ncmake --build . --config Release --target install\ncd ..\\..\\\n```\nInsert the relevant platform (`Win32/x64`) and toolset (`v142` for `VS2019`) in the `cmake` command.\n\nThis will build ZeroMQ with `libsodium`, and install `libzmq` into `C:\\libzmq`. You may need to run your shell with administrator privilege in order to write to the system disk, or change\nto a directory more suited for your needs. Once `zeromq` is installed, manually copy the `libsodium.dll` file from `libsodium\\bin\\\u003cWin32|x64\u003e\\Release\\\u003cPlatform Toolset\u003e\\dynamic` directory to\n`C:\\libzmq\\bin` directory, and the `libsodium.lib` file from the same directory to `C:\\libzmq\\lib`. Replace `C:\\libzmq` with the `CMAKE_INSTALL_PREFIX` for `zeromq` if it is different.\n\n*Note: `zeromq` builds are toolset specific, and the compiled libraries and DLLs contain the toolset number and version info in the file name. Adequately edit the `zeromq*.lib` file name in `peernet\\build_win.bat` file in case a different version and toolset is used. This behavior is not tested.*\n\n### Building CZMQ\n```cmd\ngit clone https://github.com/zeromq/czmq.git\ncd czmq\ngit checkout v4.2.1\nmkdir build\ncd build\ncmake .. -DCZMQ_BUILD_SHARED=ON -DCZMQ_BUILD_STATIC=OFF -DCMAKE_PREFIX_PATH=C:\\libzmq -DCMAKE_INSTALL_PREFIX=C:\\libzmq\ncmake --build . --config Release --target install\n```\nThis will build and install `czmq` into `C:\\libzmq`. Replace `C:\\libzmq` with the path you used in the previous step.\n\n### Building Zyre\n```cmd\ngit clone https://github.com/zeromq/zyre.git\ncd zyre\ngit checkout v2.0.1\nmkdir build\ncd build\ncmake .. -DZYRE_BUILD_SHARED=ON -DZYRE_BUILD_STATIC=OFF -DCMAKE_PREFIX_PATH=C:\\libzmq -DCMAKE_INSTALL_PREFIX=C:\\libzmq -DENABLE-DRAFTS=YES \ncmake --build . --config Release --target install\n```\nThis will build and install `zyre` into `C:\\libzmq`. Replace `C:\\libzmq` with the path you used in the previous step.\n\n### Building PeerNet\n```cmd\ngit clone https://github.com/sunipkm/peernet\ncd peernet\ngit checkout v3.0.0\nbuild_win\n``` \nThis will create the `Release` directory. The relevant files in this case are `libpeer.dll` and `libpeer.lib`. These files are copied to `C:\\libzmq\\bin` and `C:\\libzmq\\lib`, respectively.\nThe header files (`peer.h`, `peer_library.h`, `peer_private.h`) are copied from `peernet\\include` directory to `C:\\libzmq\\include`. Additionally, the `chat` example (`peerchat.exe`)\nis copied to the `C:\\libzmq\\bin` directory.\n\nFinally, `C:\\libzmq\\bin` directory should be added to `PATH` for the dynamic libraries to be loaded automatically. At this point, start `peerchat.exe` in `C:\\libzmq\\lib` from file explorer to\nensure there are no error messages related to missing DLLs. Run `peerchat.exe` in command line (which should be available anywhere if the directory is in path) to test.\n\n## Possible Security Concern\nCompared to the first version of the API where any Zyre client could snoop at our secret group name and guessed\nhow to join the local network, an extra password authentication layer has been added. However, this layer is only\nmarginally more effective as nothing prevents an adversary from snooping the group name (that is probably not\nchanging very often), and starting a peer in that group (which will become the first peer connected, hence the\nprimary arbiter of the group as it will allow/disallow the next peer to enter the group.) This is definitely going\nto prevent intrusion into an existing network, but does not prevent access after an attempt at a network restart.\nMore work is needed in this front, and ideas are very much welcome.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunipkm%2Fpeernet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsunipkm%2Fpeernet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunipkm%2Fpeernet/lists"}