sqlx mysql
This commit is contained in:
parent
39643f6466
commit
e2aa6c9eb4
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,6 +1,6 @@
|
|||||||
/target
|
/target
|
||||||
/Cargo.lock
|
/Cargo.lock
|
||||||
/.output
|
.output
|
||||||
/.vscode
|
/.vscode
|
||||||
*.pdf
|
*.pdf
|
||||||
/.data
|
/.data
|
||||||
|
|||||||
@ -20,8 +20,8 @@ serde = { version = "1.0.196", features = ["derive"] }
|
|||||||
serde_json = "1.0.113"
|
serde_json = "1.0.113"
|
||||||
serde_repr = "0.1.18"
|
serde_repr = "0.1.18"
|
||||||
sqlx = { version = "0.7.3", features = [
|
sqlx = { version = "0.7.3", features = [
|
||||||
"sqlx-sqlite",
|
"sqlx-mysql",
|
||||||
"sqlite",
|
"mysql",
|
||||||
"runtime-tokio",
|
"runtime-tokio",
|
||||||
] }
|
] }
|
||||||
structopt = "0.3.26"
|
structopt = "0.3.26"
|
||||||
|
|||||||
@ -12,14 +12,16 @@ use tokio::net::UdpSocket;
|
|||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
|
mod models;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
|
use models::create_network;
|
||||||
|
use models::init_db_pool;
|
||||||
|
|
||||||
use utils::license_ok;
|
use utils::license_ok;
|
||||||
|
|
||||||
const SERVER: &str = "127.0.0.1:7655";
|
|
||||||
|
|
||||||
async fn client(address: &str) -> Result<()> {
|
async fn client(address: &str) -> Result<()> {
|
||||||
let socket = UdpSocket::bind("127.0.0.1:0").await?;
|
let socket = UdpSocket::bind("0.0.0.0:0").await?;
|
||||||
let id = "Dejavu";
|
let id = "Dejavu";
|
||||||
let cmn = packet::Common {
|
let cmn = packet::Common {
|
||||||
version: 1,
|
version: 1,
|
||||||
@ -52,14 +54,20 @@ async fn main() -> Result<()> {
|
|||||||
// check the argument
|
// check the argument
|
||||||
let _: Ipv4Addr = args.address.parse().expect("invalid address found");
|
let _: Ipv4Addr = args.address.parse().expect("invalid address found");
|
||||||
|
|
||||||
|
// init database
|
||||||
|
init_db_pool().await?;
|
||||||
|
|
||||||
|
create_network("测试network").await?;
|
||||||
|
|
||||||
let server = format!("{}:{}", args.address, args.port);
|
let server = format!("{}:{}", args.address, args.port);
|
||||||
|
let cloned_server = server.clone();
|
||||||
let listener = UdpSocket::bind(server).await?;
|
let listener = UdpSocket::bind(server).await?;
|
||||||
|
|
||||||
let supernode = utils::SuperNode::new(listener);
|
let supernode = utils::SuperNode::new(listener, args.port);
|
||||||
utils::init_supernode(supernode).expect("failed to init supernode");
|
utils::init_supernode(supernode).expect("failed to init supernode");
|
||||||
|
|
||||||
tokio::spawn(async {
|
tokio::spawn(async move {
|
||||||
client(SERVER).await.unwrap();
|
client(&cloned_server).await.unwrap();
|
||||||
});
|
});
|
||||||
|
|
||||||
let listener = utils::get_supernode();
|
let listener = utils::get_supernode();
|
||||||
|
|||||||
@ -0,0 +1,12 @@
|
|||||||
|
-- Add migration script here
|
||||||
|
CREATE TABLE IF NOT EXISTS network (
|
||||||
|
id bigint auto_increment primary key,
|
||||||
|
uuid CHAR(32) NOT NULL,
|
||||||
|
name VARCHAR(128) NOT NULL default "",
|
||||||
|
is_fedration TINYINT(1) NOT NULL default 0,
|
||||||
|
enabled TINYINT(1) NOT NULL default 1,
|
||||||
|
network_pass VARCHAR(64) NOT NULL,
|
||||||
|
header_pass VARCHAR(64) NOT NULL,
|
||||||
|
net_addr INT UNSIGNED NOT NULL,
|
||||||
|
net_bit_len TINYINT UNSIGNED NOT NULL
|
||||||
|
);
|
||||||
52
src/bin/sdlan-sn/models/mod.rs
Normal file
52
src/bin/sdlan-sn/models/mod.rs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
use sdlan_sn_rs::utils::{gen_uuid, Result, SDLanError};
|
||||||
|
use sqlx::mysql::{MySqlPool, MySqlPoolOptions};
|
||||||
|
|
||||||
|
use crate::utils::Network;
|
||||||
|
|
||||||
|
const url: &'static str = "mysql://sdlan:sdlan-pass@localhost:3306/sdlan";
|
||||||
|
|
||||||
|
static DBPOOL: OnceCell<MySqlPool> = OnceCell::new();
|
||||||
|
|
||||||
|
pub async fn init_db_pool() -> Result<()> {
|
||||||
|
let pool = MySqlPoolOptions::new().connect(url).await?;
|
||||||
|
if let Err(_) = DBPOOL.set(pool) {
|
||||||
|
return Err(SDLanError::NormalError("init db pool failed"));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_db_pool() -> &'static MySqlPool {
|
||||||
|
DBPOOL.get().expect("db pool has not been initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_network() -> Result<Vec<Network>> {
|
||||||
|
let pool = get_db_pool();
|
||||||
|
let mut res =
|
||||||
|
sqlx::query_as::<sqlx::mysql::MySql, Network>("select * from network where id = 2")
|
||||||
|
.fetch_all(pool)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
for r in res.iter_mut() {
|
||||||
|
r.edges.insert("hello".to_string());
|
||||||
|
println!("network is {:?}", r);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_network(name: &str) -> Result<String> {
|
||||||
|
let pool = get_db_pool();
|
||||||
|
let uuid = gen_uuid();
|
||||||
|
let networkpass = gen_uuid();
|
||||||
|
let headerpass = gen_uuid();
|
||||||
|
let res = sqlx::query(r#"insert into network (`uuid`, `name`, `network_pass`, `header_pass`, `net_addr`, `net_bit_len`) values (?,?,?,?,?,?);"#)
|
||||||
|
.bind(&uuid)
|
||||||
|
.bind(name)
|
||||||
|
.bind(networkpass)
|
||||||
|
.bind(headerpass)
|
||||||
|
.bind(0)
|
||||||
|
.bind(0)
|
||||||
|
.execute(pool).await?;
|
||||||
|
Ok(uuid)
|
||||||
|
}
|
||||||
@ -2,15 +2,15 @@ use dashmap::{DashMap, DashSet};
|
|||||||
use sdlan_sn_rs::peer::IpSubnet;
|
use sdlan_sn_rs::peer::IpSubnet;
|
||||||
use sdlan_sn_rs::utils::gen_uuid;
|
use sdlan_sn_rs::utils::gen_uuid;
|
||||||
use sdlan_sn_rs::utils::MyDashMap;
|
use sdlan_sn_rs::utils::MyDashMap;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use serde::Serialize;
|
||||||
|
use sqlx::prelude::FromRow;
|
||||||
use tokio::net::UdpSocket;
|
use tokio::net::UdpSocket;
|
||||||
|
|
||||||
use crate::config;
|
use crate::config;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
use std::{
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
sync::atomic::{AtomicU32, AtomicU8},
|
|
||||||
time::{SystemTime, UNIX_EPOCH},
|
|
||||||
};
|
|
||||||
|
|
||||||
use sdlan_sn_rs::utils::{Result, SDLanError};
|
use sdlan_sn_rs::utils::{Result, SDLanError};
|
||||||
|
|
||||||
@ -85,14 +85,8 @@ impl SuperNode {
|
|||||||
fedration: Network::new("*fedration", gen_uuid(), true, 0, 0),
|
fedration: Network::new("*fedration", gen_uuid(), true, 0, 0),
|
||||||
pending: Network::new("*pending", gen_uuid(), false, 0, 0),
|
pending: Network::new("*pending", gen_uuid(), false, 0, 0),
|
||||||
ip_range: AutoIpAssign {
|
ip_range: AutoIpAssign {
|
||||||
start_ip: IpSubnet {
|
start_ip: IpSubnet::new(startip, config::DEFAULT_IP_NET_BIT_LEN),
|
||||||
net_addr: AtomicU32::new(startip),
|
end_ip: IpSubnet::new(endip, config::DEFAULT_IP_NET_BIT_LEN),
|
||||||
net_bit_len: AtomicU8::new(config::DEFAULT_IP_NET_BIT_LEN),
|
|
||||||
},
|
|
||||||
end_ip: IpSubnet {
|
|
||||||
net_addr: AtomicU32::new(endip),
|
|
||||||
net_bit_len: AtomicU8::new(config::DEFAULT_IP_NET_BIT_LEN),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
sock,
|
sock,
|
||||||
auth_key: String::from("encrypt!"),
|
auth_key: String::from("encrypt!"),
|
||||||
@ -105,17 +99,23 @@ pub struct AutoIpAssign {
|
|||||||
pub end_ip: IpSubnet,
|
pub end_ip: IpSubnet,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, FromRow, Debug)]
|
||||||
pub struct Network {
|
pub struct Network {
|
||||||
pub id: String,
|
pub uuid: String,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub is_fedration: bool,
|
pub is_fedration: bool,
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
pub network_pass: String,
|
pub network_pass: String,
|
||||||
pub header_pass: String,
|
pub header_pass: String,
|
||||||
|
#[sqlx(flatten)]
|
||||||
pub auto_ip_net: IpSubnet,
|
pub auto_ip_net: IpSubnet,
|
||||||
// 这个网络下面的节点,ip到peer uuid
|
// 这个网络下面的节点,ip到peer uuid
|
||||||
// pub edges: DashMap<u32, String>,
|
// pub edges: DashMap<u32, String>,
|
||||||
|
#[serde(skip)]
|
||||||
|
#[sqlx(skip)]
|
||||||
pub edges: DashSet<String>,
|
pub edges: DashSet<String>,
|
||||||
|
#[serde(skip)]
|
||||||
|
#[sqlx(skip)]
|
||||||
pub ip_to_edge_id: DashMap<u32, String>,
|
pub ip_to_edge_id: DashMap<u32, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,15 +123,12 @@ impl Network {
|
|||||||
fn new(name: &str, id: String, is_fedration: bool, ipnet: u32, ipnet_bitlen: u8) -> Self {
|
fn new(name: &str, id: String, is_fedration: bool, ipnet: u32, ipnet_bitlen: u8) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
id,
|
uuid: id,
|
||||||
is_fedration,
|
is_fedration,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
network_pass: gen_uuid(),
|
network_pass: gen_uuid(),
|
||||||
header_pass: gen_uuid(),
|
header_pass: gen_uuid(),
|
||||||
auto_ip_net: IpSubnet {
|
auto_ip_net: IpSubnet::new(ipnet, ipnet_bitlen),
|
||||||
net_addr: AtomicU32::new(ipnet),
|
|
||||||
net_bit_len: AtomicU8::new(ipnet_bitlen),
|
|
||||||
},
|
|
||||||
edges: DashSet::new(),
|
edges: DashSet::new(),
|
||||||
ip_to_edge_id: DashMap::new(),
|
ip_to_edge_id: DashMap::new(),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,8 +29,6 @@ mod test {
|
|||||||
use self::peer::SdlanSock;
|
use self::peer::SdlanSock;
|
||||||
use crate::packet::Common;
|
use crate::packet::Common;
|
||||||
use crate::utils::Result;
|
use crate::utils::Result;
|
||||||
use std::sync::atomic;
|
|
||||||
use std::sync::atomic::Ordering::Relaxed;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -52,10 +50,7 @@ mod test {
|
|||||||
v4: [0; 4],
|
v4: [0; 4],
|
||||||
v6: [1; 16],
|
v6: [1; 16],
|
||||||
}),
|
}),
|
||||||
dev_addr: peer::IpSubnet {
|
dev_addr: peer::IpSubnet::new(192, 24),
|
||||||
net_addr: atomic::AtomicU32::new(192),
|
|
||||||
net_bit_len: atomic::AtomicU8::new(24),
|
|
||||||
},
|
|
||||||
pub_key: "public key",
|
pub_key: "public key",
|
||||||
token: "user's token",
|
token: "user's token",
|
||||||
};
|
};
|
||||||
@ -76,14 +71,8 @@ mod test {
|
|||||||
|
|
||||||
assert_eq!(pkt1.pass, pkt2.pass);
|
assert_eq!(pkt1.pass, pkt2.pass);
|
||||||
assert_eq!(pkt1.sock, pkt2.sock);
|
assert_eq!(pkt1.sock, pkt2.sock);
|
||||||
assert_eq!(
|
assert_eq!(pkt1.dev_addr.net_addr(), pkt2.dev_addr.net_addr(),);
|
||||||
pkt1.dev_addr.net_addr.load(Relaxed),
|
assert_eq!(pkt1.dev_addr.net_bit_len(), pkt2.dev_addr.net_bit_len());
|
||||||
pkt2.dev_addr.net_addr.load(Relaxed)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
pkt1.dev_addr.net_bit_len.load(Relaxed),
|
|
||||||
pkt2.dev_addr.net_bit_len.load(Relaxed)
|
|
||||||
);
|
|
||||||
assert_eq!(pkt1.pub_key, pkt2.pub_key);
|
assert_eq!(pkt1.pub_key, pkt2.pub_key);
|
||||||
assert_eq!(pkt1.token, pkt2.token);
|
assert_eq!(pkt1.token, pkt2.token);
|
||||||
}
|
}
|
||||||
|
|||||||
50
src/peer.rs
50
src/peer.rs
@ -1,9 +1,11 @@
|
|||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::sync::atomic::{AtomicI64, AtomicU32, AtomicU8};
|
use std::os::unix::net;
|
||||||
|
use std::sync::atomic::{AtomicI64, AtomicU32, AtomicU8, Ordering};
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use sqlx::prelude::FromRow;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Peer {
|
pub struct Peer {
|
||||||
@ -30,10 +32,7 @@ impl Peer {
|
|||||||
pub fn new(id: &str) -> Self {
|
pub fn new(id: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: id.to_string(),
|
id: id.to_string(),
|
||||||
dev_addr: IpSubnet {
|
dev_addr: IpSubnet::new(0, 0),
|
||||||
net_addr: AtomicU32::new(0),
|
|
||||||
net_bit_len: AtomicU8::new(0),
|
|
||||||
},
|
|
||||||
sock: Mutex::new(SdlanSock {
|
sock: Mutex::new(SdlanSock {
|
||||||
family: 0,
|
family: 0,
|
||||||
port: 0,
|
port: 0,
|
||||||
@ -53,12 +52,51 @@ impl Peer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// IpSubnet, 对端ipv4信息
|
/// IpSubnet, 对端ipv4信息
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize, FromRow)]
|
||||||
pub struct IpSubnet {
|
pub struct IpSubnet {
|
||||||
|
net_addr: u32,
|
||||||
|
net_bit_len: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IpSubnet {
|
||||||
|
pub fn new(net_addr: u32, net_bit_len: u8) -> IpSubnet {
|
||||||
|
Self {
|
||||||
|
net_addr,
|
||||||
|
net_bit_len,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn net_addr(&self) -> u32 {
|
||||||
|
self.net_addr
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn net_bit_len(&self) -> u8 {
|
||||||
|
self.net_bit_len
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub struct IpSubnetAtomic {
|
||||||
pub net_addr: AtomicU32,
|
pub net_addr: AtomicU32,
|
||||||
pub net_bit_len: AtomicU8,
|
pub net_bit_len: AtomicU8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<IpSubnet> for IpSubnetAtomic {
|
||||||
|
fn from(value: IpSubnet) -> Self {
|
||||||
|
Self {
|
||||||
|
net_addr: AtomicU32::new(value.net_addr()),
|
||||||
|
net_bit_len: AtomicU8::new(value.net_bit_len()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IpSubnetAtomic {
|
||||||
|
pub fn new(net_addr: u32, net_bit_len: u8) -> Self {
|
||||||
|
Self {
|
||||||
|
net_addr: AtomicU32::new(net_addr),
|
||||||
|
net_bit_len: AtomicU8::new(net_bit_len),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// SdlanSock: 对端对外的ip信息,包括ipv4和ipv6
|
/// SdlanSock: 对端对外的ip信息,包括ipv4和ipv6
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct SdlanSock {
|
pub struct SdlanSock {
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
use sqlx::Error;
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, SDLanError>;
|
pub type Result<T> = std::result::Result<T, SDLanError>;
|
||||||
@ -9,6 +10,7 @@ pub enum SDLanError {
|
|||||||
ConvertError(String),
|
ConvertError(String),
|
||||||
SerializeError(String),
|
SerializeError(String),
|
||||||
EncryptError(String),
|
EncryptError(String),
|
||||||
|
DBError(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::io::Error> for SDLanError {
|
impl From<std::io::Error> for SDLanError {
|
||||||
@ -28,3 +30,9 @@ impl From<serde_json::Error> for SDLanError {
|
|||||||
Self::SerializeError(value.to_string())
|
Self::SerializeError(value.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<sqlx::Error> for SDLanError {
|
||||||
|
fn from(value: sqlx::Error) -> Self {
|
||||||
|
Self::DBError(value.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user