Allow sending messages to public keys as well

Signed-off-by: Lee Smet <lee.smet@hotmail.com>
This commit is contained in:
Lee Smet
2023-10-27 13:05:33 +02:00
parent c653c6be23
commit b01d7f0fb3
3 changed files with 78 additions and 14 deletions
+21 -5
View File
@@ -118,7 +118,7 @@ components:
description: Sender overlay IP address
type: string
format: ipv6
example: 34f:b680:ba6e:7ced:355f:346f:d97b:eecb
example: 249:abcd:0123:defa::1
src_pk:
description: Sender public key, hex encoded
type: string
@@ -147,16 +147,32 @@ components:
type: object
properties:
dst:
description: An IP in the subnet of the receiver node
type: string
format: ipv6
example: 249:abcd:0123:defa::1
$ref: '#/components/schemas/MessageDestination'
payload:
description: The message to send, base64 encoded
type: string
format: byte
example: xuV+
MessageDestination:
oneOf:
- description: An IP in the subnet of the receiver node
type: object
properties:
ip:
description: The target IP of the message
format: ipv6
example: 249:abcd:0123:defa::1
- description: The hex encoded public key of the receiver node
type: object
properties:
pk:
description: The hex encoded public key of the target node
type: string
minLength: 64
maxLength: 64
example: bb39b4a3a4efd70f3e05e37887677e02efbda14681d0acd3882bc0f754792c32
PushMessageResponse:
description: The ID generated for a message after pushing it to the system
type: object
+24 -8
View File
@@ -36,11 +36,18 @@ struct HttpServerState {
#[derive(Debug, Deserialize)]
struct MessageSendInfo {
dst: IpAddr,
dst: MessageDestination,
#[serde(with = "base64")]
payload: Vec<u8>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
enum MessageDestination {
Ip(IpAddr),
Pk(PublicKey),
}
#[derive(Serialize)]
struct MessageReceiveInfo {
id: MessageId,
@@ -52,6 +59,16 @@ struct MessageReceiveInfo {
payload: Vec<u8>,
}
impl MessageDestination {
/// Get the IP address of the destination.
fn ip(self) -> IpAddr {
match self {
MessageDestination::Ip(ip) => ip,
MessageDestination::Pk(pk) => IpAddr::V6(pk.address()),
}
}
}
impl Http {
/// Spawns a new HTTP API server on the provided listening address.
pub fn spawn(message_stack: MessageStack, listen_addr: &SocketAddr) -> Self {
@@ -126,17 +143,16 @@ async fn push_message(
State(state): State<HttpServerState>,
Json(message_info): Json<MessageSendInfo>,
) -> Result<Json<PushMessageResponse>, StatusCode> {
let dst = message_info.dst.ip();
debug!(
"Pushing new message of {} bytes to message stack for target {}",
"Pushing new message of {} bytes to message stack for target {dst}",
message_info.payload.len(),
message_info.dst
);
let id = state.message_stack.push_message(
message_info.dst,
message_info.payload,
DEFAULT_MESSAGE_TRY_DURATION,
);
let id =
state
.message_stack
.push_message(dst, message_info.payload, DEFAULT_MESSAGE_TRY_DURATION);
Ok(Json(PushMessageResponse { id }))
}
+33 -1
View File
@@ -13,7 +13,7 @@ use std::{
use aes_gcm::{aead::OsRng, AeadCore, AeadInPlace, Aes256Gcm, Key, KeyInit};
use blake2::{Blake2b, Digest};
use digest::consts::U16;
use serde::Serialize;
use serde::{de::Visitor, Deserialize, Serialize};
use tokio::{
fs::File,
io::{AsyncReadExt, AsyncWriteExt},
@@ -279,6 +279,38 @@ impl Serialize for PublicKey {
}
}
struct PublicKeyVisitor;
impl<'de> Visitor<'de> for PublicKeyVisitor {
type Value = PublicKey;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("A hex encoded public key (64 characters)")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
if v.len() != 64 {
Err(E::custom("Public key is 64 characters long"))
} else {
let mut backing = [0; 32];
faster_hex::hex_decode(v.as_bytes(), &mut backing)
.map_err(|_| E::custom("PublicKey is not valid hex"))?;
Ok(PublicKey(backing.into()))
}
}
}
impl<'de> Deserialize<'de> for PublicKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_str(PublicKeyVisitor)
}
}
impl From<[u8; 32]> for PublicKey {
/// Given a byte array, construct a `PublicKey`.
fn from(bytes: [u8; 32]) -> PublicKey {