Rust perf cpu 和内存

perf cpu

  • Cargo.toml 增加如下参数
1
2
[profile.release]
debug = true

并且以 release 模式运行代码

  • 安装 perf + FlameGraph
1
2
sudo pacman -Syu perf
git clone https://github.com/brendangregg/FlameGraph.git
Read more
实现一个简单的 channel & 介绍下 tokio channel 的实现

Golang 并发编程的核心数据结构就是 channel 了,核心观点是通过通信来共享内存,而不是通过共享内存来通信。channel 确实好用,避免了直接写各种复杂的通信原语,在 rust 中当然也有相应的实现,tokio channel 的实现非常巧妙,很值得学习。本文目的是简单介绍下 channel 的基本概念,然后实现一个最简版 mpsc unbuffered channel ,最后再介绍下 tokio 里 channel 的实现

最简版 rust channel 实现

这一部分实现一个最简版 channel ,这里的 channel 是一个有着无限 buffer 的 channel ,允许多个写入者,并且写入 channel 的操作永远不会阻塞,但是如果 channel 是空的,从 channel 消费数据的消费者会被阻塞,这里其实就是实现一个 mpsc unbuffered channel。本部分参考了 陈天 · Rust编程第一课 35 讲,陈天这一课讲得非常通俗易懂,以 TDD 的模式,从接口测试样例开始,逐步完成整个 channel 的设计。这里同样也这么做,采用 TDD 模式,并且对齐标准库的 mspc 的接口。

Read more
实现一个简单的 rust executor

本文大部分内容参考 aysnc-book,介绍了如何实现一个简单的 executor,项目地址 simple-executor

Rust 异步编程涉及到三个比较重要的概念: Future 、 executor 和 reactor 。executor 在 poll Future 的时候,会传递给 Future 一个 waker ,之后由reactor 会等待 Future 涉及的 event ,在 event 完成的时候再通过这个 waker 唤醒 executor 来继续执行这个 Future。

Future

Rust 异步编程的核心是 Future trait。Future trait 有一个关联类型 Output ,它就是 Future 完成的时返回的结果。executor 会逐步 poll 这个 Future,直到 Future 完成

1
2
3
4
5
6
7
8
pub trait Future {
#[stable(feature = "futures_api", since = "1.36.0")]
type Output;

#[lang = "poll"]
#[stable(feature = "futures_api", since = "1.36.0")]
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}

当提交 Future 给 executor 的时候,executor 会 poll 这个 Future,如果返回 Poll::Ready(Result),这个 Future 就结束了,否则返回 Poll::Pending 的话,就需要在 Future 下次可以 poll 的时候重新把 Future 提交给 executor,做这件事的其实就是通过调用 Waker 的 wake 方法

Read more
记一次有趣的查bug之旅

tokio 库提供了 copy_bidirectional 方法,可以很方便地对于实现了 AsyncRead+AsyncWrite 的数据结构实现双向拷贝。在上一篇文章(还在持续修改)中,我基于 websocket 实现了一个简单代理,使用的 websocket 库是 tokio_tungstenite

原本在client端我自定义了类似双向拷贝的函数,而不是直接使用 copy_bidirectional ,这是由于 tokio_tungstenite 基于 TcpStream 构建的 WebSocketStream 并没有实现 AsyncRead+AsyncWrite 。另外,由于 tokio_tungstenite 返回的的 WebSocketStream 没有对外暴露好用的 read 和 write 方法,只是实现了 Sink 和 Stream,不过它对外提供了 split 方法,可以将 stream 的读写分别拆分开来,拆分出来的读无脑将读到的数据写到 TcpStream ,拆分出来的写无脑将从 TcpStream 读到的写到自己的 stream 。这样带来的问题是,在读写分离的情况下,不能够优雅的感知 Close 包,无法优雅的退出上述读写的流程。简单展示下原本的实现:

Read more
使用rust实现sock5代理

熟悉一门语言的第一步可能是用它写个代理吧。看了很久 rust 的语法,工作上派不上啥用场,只能自己制造需求了,希望以后能找份写 rust 的工作,或者可以自由学东西的工作。

这个代理有什么特点?

  • 基于 rust

主要目的是练习写 rust ,另外 rust 安全高效

  • 基于 tls websocket

过神秘的墙需要加密连接,否则容易毙掉。常见的做法类似 shadowsocks ,自定义加密协议,但是这种比较麻烦,偷懒直接使用 TLS websocket 来做这件事

  • 池化 websocket 连接

池化连接的好处不容多说,少了建立连接的时间,代理速度更快

代理大体流程是这样的:

rust-proxy-pipeline

代码地址:https://github.com/suikammd/rust-proxy

Read more
2021 bytedance CTF writeup

小白的CTF初体验,感谢海大佬的耐心指导!

题型包括SQL注入、SSRF、XSS、权限绕过、信息泄漏、安卓。字节出的大部分题型都包含多道题,题目的难度也是由浅入深的。比如SQL注入,你可以看到第一道题的golang源码,直接就可以看到gorm是如何拼接字符串的,接下来的几道题目会逐渐减少对参赛者暴露的信息。

优秀工具介绍:

  1. burp 作为proxy抓包,把请求配知道repeater,可以任意修改请求参数来测试
  2. sqlmap sql注入解题利器
  3. requestbin.com 随意生成bin,可以接收测试请求
  4. cloudflare worker 快速创建测试服务
Read more
限流器

限流器主要是防止高并发流量打垮服务,常见的限流器算法有计数器、令牌桶和漏桶,令牌桶在令牌不足时会直接拒绝请求,漏桶在请求不足时会阻塞请求。本文实现一个允许适量流量激增的限流器。只是写着玩,不要喷我写的挫谢谢。

Read more
理解golang函数传递slice

开始看golang的时候,最纠结的就是函数传递slice,这个slice到底有没有发生变化。最近发现周围的同事也没有弄清楚,于是打算仔细看下,在函数里修改传递的slice会不会改变原来的slice。

slice 结构

首先从slice的结构入手,可以看到slice底层其实就是一个数组

1
2
3
4
5
6
7
8
9
10
11
type slice struct {
array unsafe.Pointer
len int
cap int
}

type SliceHeader struct {
Data uintptr
Len int
Cap int
}
Read more
基于antlr的词法和语法分析

最近工作经常跟antlr打交道,一开始半懂不懂,各种瞎写胡试,也能work。工作做完之后就想系统了解下编译器前端到底做了哪些事情,也就是词法分析和语法分析究竟做了什么,以及antlr的lexer和parser的语法。

编译器前端到底做了哪些事情

从一个比较high level的角度看待编译器前端对字符串的处理流程,第一步是做词法解析,将字符串解析成Token序列,第二步是做语法分析,根据语法匹配命中相应的语法规则。

  1. 词法分析

    以这句SPL查询search id |stats count by id 为例,词法分析做的事情就是把这个字符串解析成Token序列:search、id、stats、count、by、|,同时也会拿到这些token对应的类型。

  2. 语法分析

    词法分析的结果作为语法分析器的输入,经过语法分析之后会确定这个SPL的AST语法树。

Read more
搭建本地https服务器
  1. 生成证书
    (1)生成rsa密钥 openssl genrsa -des3 -out server.key 1024
    (2)去掉密钥文件保护密码 openssl rsa -in server.key -out server.key
    (3)生成ca对应的csr openssl req -new -key server.key -out server.csr
    (4)自签名 openssl x509 -req -days 1024 -in server.csr -signkey server.key -out server.crt
    (5)cat server.crt server.key > server.pem

Read more