Skip to content

Commit d6e8586

Browse files
committed
Release v2.0.0-beta1
0 parents  commit d6e8586

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2843
-0
lines changed

README.md

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
![Husarnet logo](images/logo.svg)
2+
3+
# Husarnet for Arduino ESP32
4+
5+
Husarnet is a low latency, lightweight, privacy preserving P2P VPN. If you want
6+
to know more go to the [Husarnet's webpage](https://husarnet.com/) or directly
7+
to the [documentation page](https://docs.husarnet.com/).
8+
9+
This repository only contains library code for the Arduino IDE. If you want
10+
to use Husarnet with the PlatformIO IDE, go to the [husarnet-esp32-platformio](https://github.com/husarnet/husarnet-esp32-platformio).
11+
12+
Due to the way precompiled libraries work in Arduino the static library for each
13+
target must be placed in a seperate directory. Due to this `libhusarnet.a` is
14+
duplicated few times in different folders.
15+
16+
## Installation and usage
17+
18+
Coming soon...
19+
20+
## Examples
21+
22+
You'll find full examples in our [examples](examples) directory.
23+
24+
Start with a [simple-webserver](examples/simple-webserver) for a fairly minimal example.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#include <Arduino.h>
2+
#include <WiFi.h>
3+
#include <WebServer.h>
4+
#include <husarnet.h>
5+
6+
// WiFi credentials
7+
#define WIFI_SSID = "wifi-network";
8+
#define WIFI_PASS = "wifi-password";
9+
10+
// Husarnet credentials
11+
#define HOSTNAME = "esp32-arduino-webserver";
12+
#define JOIN_CODE = "xxxxxxxxxxxxxxxxxxxx";
13+
14+
HusarnetClient husarnet;
15+
WebServer server(80);
16+
17+
void handleRoot() {
18+
server.send(200, "text/plain", "Hello Husarnet!");
19+
}
20+
21+
void setup() {
22+
Serial.begin(115200);
23+
24+
// Connect to the WiFi network
25+
WiFi.mode(WIFI_STA);
26+
WiFi.begin(WIFI_SSID, WIFI_PASS);
27+
28+
Serial.println("Connecting to WiFi");
29+
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
30+
Serial.printf("WiFi connection failure (err: %d)\n", WiFi.status());
31+
delay(5000);
32+
ESP.restart();
33+
}
34+
35+
Serial.print("Local IP: ");
36+
Serial.println(WiFi.localIP());
37+
38+
// Join the Husarnet network
39+
husarnet.join(HOSTNAME, JOIN_CODE);
40+
41+
while(!husarnet.isJoined()) {
42+
Serial.println("Waiting for Husarnet network...");
43+
delay(1000);
44+
}
45+
Serial.println("Husarnet network joined");
46+
47+
Serial.print("Husarnet IP: ");
48+
Serial.println(husarnet.getIpAddress().c_str());
49+
50+
// Start the web server
51+
server.on("/", handleRoot);
52+
server.begin();
53+
Serial.println("HTTP server started");
54+
}
55+
56+
void loop() {
57+
// Handle incoming connections
58+
server.handleClient();
59+
delay(2);
60+
}

images/logo.svg

+18
Loading

library.properties

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name=Husarnet ESP32
2+
version=2.0.0-beta1
3+
author=Husarnet
4+
maintainer=Milosz Lagan, [email protected]
5+
sentence=Connect your devices using secure P2P network layer for robots and IoT.
6+
paragraph=Look at docs.husarnet.com for information how to configure your project!
7+
category=Communication
8+
url=https://husarnet.com/
9+
includes=husarnet.h
10+
precompiled=true

src/esp32/libhusarnet.a

27.5 MB
Binary file not shown.

src/esp32c2/libhusarnet.a

27.5 MB
Binary file not shown.

src/esp32c3/libhusarnet.a

27.5 MB
Binary file not shown.

src/esp32c5/libhusarnet.a

27.5 MB
Binary file not shown.

src/esp32c6/libhusarnet.a

27.5 MB
Binary file not shown.

src/esp32p4/libhusarnet.a

27.5 MB
Binary file not shown.

src/esp32s2/libhusarnet.a

27.5 MB
Binary file not shown.

src/esp32s3/libhusarnet.a

27.5 MB
Binary file not shown.

src/husarnet.h

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#pragma once
2+
3+
// User-facing API is defined in the
4+
// "husarnet/port/esp32/user_interface.h" header
5+
// in the included Husarnet submodule.
6+
#include "husarnet/ports/esp32/user_interface.h"
7+
8+
#if defined(ARDUINO) && !defined(ARDUINO_ARCH_ESP32)
9+
#error "This library only supports boards from the ESP32 family."
10+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) 2024 Husarnet sp. z o.o.
2+
// Authors: listed in project_root/README.md
3+
// License: specified in project_root/LICENSE.txt
4+
#pragma once
5+
#include <string>
6+
7+
#include <husarnet/husarnet_manager.h>
8+
9+
#include "husarnet/identity.h"
10+
11+
#include "httplib.h"
12+
#include "nlohmann/json.hpp"
13+
14+
class DashboardApiProxy {
15+
private:
16+
HusarnetManager* manager;
17+
18+
public:
19+
DashboardApiProxy(HusarnetManager* manager) : manager(manager)
20+
{
21+
}
22+
23+
void signAndForward(
24+
const httplib::Request& req,
25+
httplib::Response& res,
26+
const std::string& path);
27+
};

src/husarnet/api_server/server.h

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright (c) 2024 Husarnet sp. z o.o.
2+
// Authors: listed in project_root/README.md
3+
// License: specified in project_root/LICENSE.txt
4+
#pragma once
5+
#include <chrono>
6+
#include <condition_variable>
7+
#include <mutex>
8+
#include <string>
9+
10+
#include "husarnet/api_server/dashboard_api_proxy.h"
11+
12+
#include "httplib.h"
13+
#include "nlohmann/json.hpp"
14+
15+
class HusarnetManager;
16+
17+
namespace httplib {
18+
struct Request;
19+
struct Response;
20+
} // namespace httplib
21+
22+
class ApiServer {
23+
private:
24+
HusarnetManager* manager;
25+
DashboardApiProxy* proxy;
26+
std::mutex mutex;
27+
std::condition_variable cv;
28+
29+
void returnSuccess(
30+
const httplib::Request& req,
31+
httplib::Response& res,
32+
nlohmann::json result);
33+
void returnSuccess(const httplib::Request& req, httplib::Response& res);
34+
35+
void returnInvalidQuery(
36+
const httplib::Request& req,
37+
httplib::Response& res,
38+
std::string errorString);
39+
void returnError(
40+
const httplib::Request& req,
41+
httplib::Response& res,
42+
std::string errorString);
43+
44+
bool validateSecret(const httplib::Request& req, httplib::Response& res);
45+
46+
nlohmann::json getStandardReply();
47+
48+
bool requireParams(
49+
const httplib::Request& req,
50+
httplib::Response& res,
51+
std::list<std::string> paramNames);
52+
53+
public:
54+
ApiServer(HusarnetManager* manager, DashboardApiProxy* proxy);
55+
56+
void runThread();
57+
void waitStarted();
58+
};

src/husarnet/compression_layer.h

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (c) 2024 Husarnet sp. z o.o.
2+
// Authors: listed in project_root/README.md
3+
// License: specified in project_root/LICENSE.txt
4+
#pragma once
5+
#include <string>
6+
7+
#include "husarnet/device_id.h"
8+
#include "husarnet/husarnet_manager.h"
9+
#include "husarnet/layer_interfaces.h"
10+
#include "husarnet/string_view.h"
11+
12+
class ConfigStorage;
13+
class HusarnetManager;
14+
class PeerContainer;
15+
16+
class CompressionLayer : public BidirectionalLayer {
17+
private:
18+
#pragma clang diagnostic push
19+
#pragma clang diagnostic ignored "-Wunused-private-field"
20+
HusarnetManager* manager;
21+
#pragma clang diagnostic pop
22+
23+
ConfigStorage& config;
24+
PeerContainer* peerContainer;
25+
26+
std::string compressionBuffer;
27+
std::string cleartextBuffer;
28+
29+
bool shouldProceed(DeviceId source);
30+
31+
public:
32+
CompressionLayer(HusarnetManager* manager);
33+
34+
void onUpperLayerData(DeviceId peerId, string_view data);
35+
void onLowerLayerData(DeviceId peerId, string_view data);
36+
};

src/husarnet/config_storage.h

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// Copyright (c) 2024 Husarnet sp. z o.o.
2+
// Authors: listed in project_root/README.md
3+
// License: specified in project_root/LICENSE.txt
4+
#pragma once
5+
#include <functional>
6+
#include <list>
7+
#include <stdexcept>
8+
#include <string>
9+
10+
#include "husarnet/config_storage.h"
11+
#include "husarnet/ipaddress.h"
12+
13+
#include "enum.h"
14+
#include "nlohmann/json.hpp"
15+
16+
using namespace nlohmann; // json
17+
18+
// Remember to add sane defaults in husarnet_config.h
19+
// Keep the naming consistent, i.e use only enable* format, and *not* *enable or
20+
// disable*
21+
BETTER_ENUM(
22+
InternalSetting,
23+
int,
24+
websetupSecret = 1 // string
25+
)
26+
BETTER_ENUM(
27+
UserSetting,
28+
int,
29+
dashboardFqdn = 1, // string
30+
enableWhitelist = 2, // bool
31+
interfaceName = 3, // string
32+
daemonApiPort = 4, // int
33+
enableCompression = 5, // bool
34+
enableUdpTunneling = 6, // bool
35+
enableTcpTunneling = 7, // bool
36+
enableUdp = 8, // bool
37+
enableMulticast = 9, // bool
38+
overrideBaseAddress = 10, // inet
39+
overrideSourcePort = 11, // int
40+
extraAdvertisedAddress = 12, // inet
41+
joinCode = 13, // string, this will never be persisted
42+
hostname = 14, // string, this will never be persisted
43+
enableHooks = 15, // bool
44+
logVerbosity = 16, // int
45+
enableNotifications = 17, // bool, orphaned
46+
daemonApiAddress = 18, // ip
47+
daemonApiInterface = 19 // string
48+
)
49+
50+
const std::string trueValue = "true";
51+
const std::string falseValue =
52+
"false"; // This is not strictly checked. It's here just to provide a known
53+
// placeholder
54+
55+
class HusarnetManager;
56+
57+
class ConfigStorage {
58+
HusarnetManager* manager;
59+
std::function<std::string()> readFunc;
60+
std::function<void(std::string)> writeFunc;
61+
std::map<UserSetting, std::string> userDefaults;
62+
std::map<UserSetting, std::string> userOverrides;
63+
std::map<InternalSetting, std::string> internalDefaults;
64+
65+
json currentData;
66+
67+
bool shouldSaveImmediately = true;
68+
bool hostCacheInvalidated = true;
69+
70+
std::string serialize();
71+
void deserialize(std::string blob);
72+
73+
void save();
74+
75+
public:
76+
ConfigStorage(
77+
HusarnetManager* manager,
78+
std::function<std::string()> readFunc,
79+
std::function<void(std::string)> writeFunc,
80+
std::map<UserSetting, std::string> userDefaults,
81+
std::map<UserSetting, std::string> userOverrides,
82+
std::map<InternalSetting, std::string> internalDefaults);
83+
84+
ConfigStorage(ConfigStorage&) = delete;
85+
86+
void updateHostsInSystem();
87+
88+
json getCurrentData() const;
89+
90+
void groupChanges(std::function<void()> f);
91+
92+
void hostTableAdd(std::string hostname, IpAddress address);
93+
void hostTableRm(std::string hostname);
94+
std::map<std::string, IpAddress> getHostTable() const;
95+
void hostTableClear();
96+
97+
void whitelistAdd(IpAddress address);
98+
void whitelistRm(IpAddress address);
99+
bool isOnWhitelist(IpAddress address) const;
100+
std::list<IpAddress> getWhitelist() const;
101+
void whitelistClear();
102+
103+
void setInternalSetting(InternalSetting setting, std::string value);
104+
void setInternalSetting(InternalSetting setting, const char* value);
105+
void setInternalSetting(InternalSetting setting, bool value);
106+
void setInternalSetting(InternalSetting setting, int value);
107+
void clearInternalSetting(InternalSetting setting);
108+
109+
std::string getInternalSetting(InternalSetting setting) const;
110+
bool getInternalSettingBool(InternalSetting setting) const;
111+
int getInternalSettingInt(InternalSetting setting) const;
112+
113+
bool isInternalSettingEmpty(InternalSetting setting) const;
114+
115+
void setUserSetting(UserSetting setting, std::string value);
116+
void setUserSetting(UserSetting setting, const char* value);
117+
void setUserSetting(UserSetting setting, bool value);
118+
void setUserSetting(UserSetting setting, int value);
119+
void setUserSetting(UserSetting setting, InetAddress inet);
120+
void clearUserSetting(UserSetting setting);
121+
122+
bool isUserSettingOverriden(UserSetting setting) const;
123+
std::string getPersistentUserSetting(UserSetting setting) const;
124+
void persistUserSettingOverride(UserSetting setting);
125+
126+
std::string getUserSetting(UserSetting setting) const;
127+
bool getUserSettingBool(UserSetting setting) const;
128+
int getUserSettingInt(UserSetting setting) const;
129+
InetAddress getUserSettingInet(UserSetting setting) const;
130+
IpAddress getUserSettingIp(UserSetting setting) const;
131+
132+
std::map<std::string, std::string> getUserSettings() const;
133+
134+
void printSettings() const;
135+
};

0 commit comments

Comments
 (0)