added token in common
This commit is contained in:
parent
6e66713b43
commit
50c874e542
39
docs/api.md
Normal file
39
docs/api.md
Normal file
@ -0,0 +1,39 @@
|
||||
# sdlan web api文档
|
||||
sdlan为前端提供了若干api。其中,所有的api都使用POST方法,将数据以json消息体的方式提交给服务端。服务端根据具体处理结果,返回json数据。
|
||||
|
||||
## 1. 返回消息体
|
||||
sdlan api的所有返回的消息体都遵循如下格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": $int,
|
||||
"message": $object,
|
||||
"error": $string,
|
||||
}
|
||||
```
|
||||
|
||||
其中,code为0代表请求成功,返回的内容存放在`message`字段,`error`字段为空字符串;反之,如果请求失败,则`code`不为0,同时,`message`为空字符串,`error`字段为错误描述字符串。
|
||||
|
||||
在后面的描述中,如果请求成功,则默认返回的`code`为0,`error`为空字符串,而`message`会写明结构;如果返回失败,则`message`为空字符串,`code`和`error`会根据情况标明。
|
||||
|
||||
## 2. 消息请求参数说明
|
||||
在实际操作过程中,用户会需要先注册,注册成功之后,需要先使用用户名和密码进行登录,密码验证成功之后,后台会返回一个token,该token有效期为一个小时,在登录成功之后所有其他的接口(即除了register和login接口),在发起请求的时候,都需要在请求头的header里面带上`token`,否则会权限热症失败,返回`code`为400,`error`为`“unauthorized”`
|
||||
|
||||
## 3. 实际接口
|
||||
实际接口分成几个类别列举。
|
||||
|
||||
### 4.1. 用户操作
|
||||
用户操作包括用户注册,登录,登出,创建/删除/查看register-token(用于节点登录时填写的token);修改密码等一系列关于用于的操作。
|
||||
|
||||
### 4.2. 网络操作
|
||||
网络操作主要包括网络的创建、列举、删除、路由(给网络添加、删除一系列路由信息)等操作。
|
||||
|
||||
### 4.3. 节点操作
|
||||
节点操作包括对节点的授权、取消授权、在网络之间移动等操作。
|
||||
|
||||
#### 4.3.1 授权节点
|
||||
该接口用于对未授权的节点进行授权操作。
|
||||
|
||||
```
|
||||
POST /peer/authorize
|
||||
```
|
||||
@ -3,7 +3,7 @@ pub const FLAGS_TYPE_MASK: u16 = 0x001f;
|
||||
pub const FLAGS_BITS_MASK: u16 = 0xffe0;
|
||||
|
||||
// common头的flags里面的flag,可以组合
|
||||
// 表示从SN发送过来的REGISTER_SUPER消息,主要用于SN注册
|
||||
// 表示从SN主动发送到其他SN的消息
|
||||
pub const SDLNA_FLAGS_FEDERATION: u16 = 0x0010;
|
||||
pub const SDLAN_FLAGS_FROM_SN: u16 = 0x0020;
|
||||
pub const SDLAN_FLAGS_SOCKET: u16 = 0x0040;
|
||||
|
||||
@ -5,8 +5,7 @@ use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||
#[derive(Debug, PartialEq, Serialize_repr, Deserialize_repr, Copy, Clone)]
|
||||
#[repr(u8)]
|
||||
pub enum CommandType {
|
||||
AuthorizePeer,
|
||||
MovePeer,
|
||||
MovePeer = 1,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
@ -15,6 +14,16 @@ pub struct Command {
|
||||
pub message: Value,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct MovePeerCommandReq {
|
||||
pub from_id: String,
|
||||
pub to_id: String,
|
||||
pub peer_id: String,
|
||||
pub new_ip: u32,
|
||||
pub net_bit_len: u8,
|
||||
pub user_id: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct CommandResp {
|
||||
cmd_type: CommandType,
|
||||
|
||||
@ -11,7 +11,11 @@ use crate::utils::*;
|
||||
pub struct Common<'a> {
|
||||
pub packet_id: u16,
|
||||
pub version: u8,
|
||||
// client's uuid
|
||||
pub id: &'a str,
|
||||
|
||||
pub token: u64,
|
||||
|
||||
pub ttl: u8,
|
||||
// packet type
|
||||
pub pc: PacketType,
|
||||
@ -25,6 +29,8 @@ impl<'a> Common<'a> {
|
||||
encode_u8(&mut result, self.version);
|
||||
|
||||
encode_buf_without_size(&mut result, &self.id.as_bytes(), 32);
|
||||
// result.extend_from_slice(self.id.as_bytes());
|
||||
result.extend_from_slice(&self.token.to_be_bytes());
|
||||
// encode_buf_with_size_1(&mut result, self.id.as_bytes());
|
||||
|
||||
encode_u8(&mut result, self.ttl);
|
||||
@ -37,10 +43,11 @@ impl<'a> Common<'a> {
|
||||
result
|
||||
}
|
||||
|
||||
pub fn from_slice(value: &'a [u8]) -> Result<(Common<'a>, &'a [u8])> {
|
||||
let id_len = 32;
|
||||
pub fn from_slice(value: &'a [u8]) -> Result<(Common, &'a [u8])> {
|
||||
const id_len: usize = 32;
|
||||
const token_len: usize = 8;
|
||||
|
||||
if value.len() < 7 + id_len {
|
||||
if value.len() < 7 + id_len + token_len {
|
||||
return Err("common header length error".into());
|
||||
}
|
||||
let packet_id = u16::from_be_bytes(value[0..2].try_into().unwrap());
|
||||
@ -51,26 +58,36 @@ impl<'a> Common<'a> {
|
||||
Ok(s) => s,
|
||||
Err(e) => return Err(SDLanError::ConvertError(e.to_string())),
|
||||
};
|
||||
// let id = u64::from_be_bytes(v1);
|
||||
id = id.trim_end_matches('\0');
|
||||
let ttl = value[3 + id_len];
|
||||
let flags = BigEndian::read_u16(&value[4 + id_len..6 + id_len]);
|
||||
let pc = value[6 + id_len];
|
||||
|
||||
let token = u64::from_be_bytes(
|
||||
value[3 + id_len..3 + id_len + token_len]
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let ttl = value[3 + id_len + token_len];
|
||||
let flags = BigEndian::read_u16(&value[4 + id_len + token_len..6 + id_len + token_len]);
|
||||
let pc = value[6 + id_len + token_len];
|
||||
|
||||
let common = Self {
|
||||
packet_id,
|
||||
version,
|
||||
id,
|
||||
ttl,
|
||||
token,
|
||||
pc: pc.into(),
|
||||
flags: flags,
|
||||
};
|
||||
Ok((common, &value[7 + id_len..]))
|
||||
Ok((common, &value[7 + id_len + token_len..]))
|
||||
}
|
||||
|
||||
pub fn from_old_common(cmn: &'a Common) -> Self {
|
||||
return Common {
|
||||
packet_id: cmn.packet_id,
|
||||
id: cmn.id,
|
||||
token: cmn.token,
|
||||
version: cmn.version,
|
||||
ttl: cmn.ttl,
|
||||
pc: cmn.pc,
|
||||
@ -82,6 +99,7 @@ impl<'a> Common<'a> {
|
||||
return Common {
|
||||
packet_id: 0,
|
||||
id,
|
||||
token: 0,
|
||||
version: 1,
|
||||
ttl: 2,
|
||||
pc: PacketType::PKTInvalid,
|
||||
@ -169,11 +187,13 @@ mod test {
|
||||
packet_id: 0,
|
||||
version: 0,
|
||||
id,
|
||||
token: 0,
|
||||
ttl: 2,
|
||||
pc: 1.into(),
|
||||
flags: 0,
|
||||
};
|
||||
let value1 = common.encode();
|
||||
println!("value1.len: {}", value1.len());
|
||||
let (common2, _) = Common::from_slice(&value1).unwrap();
|
||||
println!("common2 = {:?}", common2);
|
||||
assert_eq!(common.id, common2.id);
|
||||
|
||||
@ -20,9 +20,8 @@ pub struct RegisterSuper<'a> {
|
||||
|
||||
// 自身的公钥
|
||||
pub pub_key: String,
|
||||
|
||||
// user's token, can be used to specify a user
|
||||
pub token: &'a str,
|
||||
// pub token: &'a str,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -74,7 +73,7 @@ mod test {
|
||||
net_bit_len: 24,
|
||||
},
|
||||
pub_key: "public key".to_string(),
|
||||
token: "user's token",
|
||||
// token: "user's token",
|
||||
};
|
||||
let res = serde_json::to_string(&pkt1).unwrap();
|
||||
println!("unmarshaled as {}", res);
|
||||
@ -87,6 +86,7 @@ mod test {
|
||||
packet_id: 0,
|
||||
version: 1,
|
||||
id: "asxalex",
|
||||
token: 0,
|
||||
ttl: 128,
|
||||
pc: PacketType::PKTRegisterSuper,
|
||||
flags: config::SDLAN_FLAGS_FROM_SN,
|
||||
@ -112,7 +112,7 @@ mod test {
|
||||
net_bit_len: 24,
|
||||
},
|
||||
pub_key: "public key".to_string(),
|
||||
token: "user's token",
|
||||
// token: "user's token",
|
||||
};
|
||||
(cmn1, pkt1)
|
||||
}
|
||||
@ -147,7 +147,7 @@ mod test {
|
||||
assert_eq!(pkt1.dev_addr.net_addr(), pkt2.dev_addr.net_addr(),);
|
||||
assert_eq!(pkt1.dev_addr.net_bit_len(), pkt2.dev_addr.net_bit_len());
|
||||
assert_eq!(pkt1.pub_key, pkt2.pub_key);
|
||||
assert_eq!(pkt1.token, pkt2.token);
|
||||
// assert_eq!(pkt1.token, pkt2.token);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
100
src/peer.rs
100
src/peer.rs
@ -1,11 +1,13 @@
|
||||
#![allow(unused)]
|
||||
use super::utils::Result;
|
||||
use dashmap::DashMap;
|
||||
use dashmap::DashSet;
|
||||
use futures::future::BoxFuture;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::prelude::FromRow;
|
||||
use std::default::Default;
|
||||
use std::future::Future;
|
||||
use std::hash::Hasher;
|
||||
use std::sync::atomic::{AtomicU32, AtomicU64, AtomicU8, Ordering};
|
||||
use std::sync::RwLock;
|
||||
|
||||
@ -197,6 +199,7 @@ use crate::utils::SDLanError;
|
||||
use std::pin::Pin;
|
||||
pub struct PeerMap {
|
||||
pub peers: DashMap<String, Arc<Peer>>,
|
||||
// from client's uuid, to the
|
||||
// ip to peer's uuid, the ip is the logical ip
|
||||
// of tun
|
||||
// pub peer_ip_map: DashMap<u32, String>,
|
||||
@ -264,6 +267,103 @@ impl PeerMap {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EdgeInfo {
|
||||
pub edges: DashSet<String>,
|
||||
ip_to_edge_id: DashMap<u32, String>,
|
||||
}
|
||||
|
||||
impl Default for EdgeInfo {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl EdgeInfo {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
edges: DashSet::new(),
|
||||
ip_to_edge_id: DashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
// purge peer in self and in PeerMap, together
|
||||
pub fn purge_peer(&self, id: &str, pm: &PeerMap) {
|
||||
if let Some((_k, v)) = pm.peers.remove(id) {
|
||||
let ip = v.dev_addr.net_addr();
|
||||
self.ip_to_edge_id.remove(&ip);
|
||||
}
|
||||
self.edges.remove(id);
|
||||
}
|
||||
|
||||
pub fn unbind_peer(&self, id: &str, ip: u32) {
|
||||
self.edges.remove(id);
|
||||
if ip != 0 {
|
||||
self.ip_to_edge_id.remove(&ip);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_peer_with_id<'a>(&self, id: &'a str, pm: &'a PeerMap) -> Option<Arc<Peer>> {
|
||||
if !self.edges.contains(id) {
|
||||
return None;
|
||||
} else {
|
||||
if let Some(p) = pm.peers.get(id) {
|
||||
Some(p.clone())
|
||||
} else {
|
||||
// edge conatains, but global peermap does not
|
||||
// remove it in edges
|
||||
self.edges.remove(id);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter_peer_with_id<'a, F>(&'a self, pm: &'a PeerMap, f: F) -> Option<(String, Arc<Peer>)>
|
||||
where
|
||||
F: Fn(&Arc<Peer>) -> bool,
|
||||
{
|
||||
for id in self.edges.iter() {
|
||||
if let Some(temp) = pm.peers.get(&*id) {
|
||||
if f(&temp) {
|
||||
return Some((id.to_owned(), temp.clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_peer_with_ip(&self, ip: u32, pm: &PeerMap) -> Option<Arc<Peer>> {
|
||||
if let Some(id) = self.ip_to_edge_id.get(&ip) {
|
||||
if let Some(p) = pm.peers.get(&*id) {
|
||||
return Some(p.clone());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn contains(&self, id: &str) -> bool {
|
||||
self.edges.contains(id)
|
||||
}
|
||||
|
||||
pub fn insert_peer(&self, ip: u32, id: String) {
|
||||
if ip != 0 {
|
||||
self.ip_to_edge_id.insert(ip, id.clone());
|
||||
}
|
||||
self.edges.insert(id);
|
||||
}
|
||||
|
||||
// 重新绑定一个id
|
||||
pub fn rebind_peer_ip(&self, ip: u32, oldid: &str, newid: &str, pm: &PeerMap) {
|
||||
if let Some((_, v)) = pm.peers.remove(oldid) {
|
||||
pm.peers.insert(newid.to_owned(), v);
|
||||
}
|
||||
self.ip_to_edge_id.remove(&ip);
|
||||
self.ip_to_edge_id.insert(ip, newid.to_owned());
|
||||
self.edges.remove(oldid);
|
||||
self.edges.insert(newid.to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::config::AF_INET;
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
use std::{convert::From, net::AddrParseError, string::ParseError};
|
||||
|
||||
use aes::cipher::typenum::IsLessOrEqual;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, SDLanError>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SDLanError {
|
||||
IOError(std::io::Error),
|
||||
IOError(String),
|
||||
NormalError(&'static str),
|
||||
ConvertError(String),
|
||||
SerializeError(String),
|
||||
@ -12,9 +14,22 @@ pub enum SDLanError {
|
||||
DBError(String),
|
||||
}
|
||||
|
||||
impl SDLanError {
|
||||
pub fn as_str(&self) -> &str {
|
||||
match *self {
|
||||
Self::IOError(ref e) => e,
|
||||
Self::NormalError(ref s) => s,
|
||||
Self::ConvertError(ref e) => e,
|
||||
Self::SerializeError(ref e) => e,
|
||||
Self::EncryptError(ref e) => e,
|
||||
Self::DBError(ref e) => e,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for SDLanError {
|
||||
fn from(value: std::io::Error) -> Self {
|
||||
Self::IOError(value)
|
||||
Self::IOError(value.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -31,7 +31,15 @@ impl<T> MyDashMap<T> {
|
||||
}
|
||||
}
|
||||
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub fn get_timestamp_after_duration(d: Duration) -> u64 {
|
||||
if let Some(t) = SystemTime::now().checked_add(d) {
|
||||
t.duration_since(UNIX_EPOCH).unwrap().as_secs()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
pub fn get_current_timestamp() -> u64 {
|
||||
SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
|
||||
@ -3,3 +3,11 @@ use uuid::Uuid;
|
||||
pub fn gen_uuid() -> String {
|
||||
format!("{:032x}", Uuid::new_v4().as_u128())
|
||||
}
|
||||
|
||||
pub fn gen_uuid_u64() -> u64 {
|
||||
(Uuid::new_v4().as_u128() >> 64) as u64
|
||||
}
|
||||
|
||||
pub fn gen_uuid_u128() -> u128 {
|
||||
Uuid::new_v4().as_u128()
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user