這東西太複雜了, 看到不錯的連結就備忘一下:
- Licenses - Choose a License: 簡化的比較表, 容易看出差異
- Comparison of free and open-source software licenses - Wikipedia
- licensing - What "sublicense" actually means? - Programmers Stack Exchange: BSD 和 MIT 不同, 前者不允許改 license, 後者可 (更寛鬆)
這東西太複雜了, 看到不錯的連結就備忘一下:
最近看到不錯的寫法, 備忘一下。
通常我們不希望 main thread 被 block [*1], 所以會另外開 worker thread 處理耗 CPU 的工作。主要的需求是避免 block main thread, 其次是縮短完成工作的時間。
由於 main thread 和 worker thread 需要互相傳遞一些資料, 有可能造成 race condition, 導致程式行為有時不正確或是掛掉。這裡討論幾種避免 race condition 的作法。
worker thread 全部函式都用同一個 lock 保護。
和上個作法類似, 不過資料分群用不同 lock 保護。
如果資料只有一個 thread 會用到, 就直接轉交給另一個 thread (改變 ownership)。若兩個 thread 都會用到, 先複製一份再轉交給另一個 thread。沒有共享的資料, 就不需用 lock 保護了 (但仍需透過 message loop 或 queue 傳遞資料到另一個 thread)。
需要同步資料的時候, 記得只能允許一個方向的 block。比方說 main thread 可以透過 conditional variable 來 block worker thread, 但不允許反過來的操作, 這樣就不會有 dead lock。
每個函式都要放 assert 確保函式在正確的 thread 執行。若一個 class 有兩份資料分別在兩個 thread 下執行的話, 可以考慮訂兩個 struct, 比方說 MainData 和 WorkerData, 然後透過 private method 存取資料, 藉此確保 thread safe:
// C++
class MyClass
{
public:
...
private:
MainData& GetMainData();
WorkerData& GetWorkerData();
struct MainData {
...
};
struct WorkerData {
...
};
MainData m_mainData;
WorkerData m_workerData;
};
MainData& MyClass::GetMainData()
{
assert(InMainThread());
return m_mainData;
}
WorkerData& MyClass::GetWorkerData()
{
assert(InWorkerThread());
return m_workerData;
}
這樣程式寫錯時會造成 assert failed, 可以很快地修正。
*1 比方說 daemon 的 main thread 會不斷收新的連線, GUI 的 main thread 會收使用者的輸入。main thread 被 block 而沒有反應的話, 使用者會覺得軟體有問題。
前陣子用 node.js 寫了一個上線的服務, 沒有意外的話接下來有一大段時間不會碰 node.js。備忘一下有用到和以後可能會用到的東西。
主要弱點
其它
看到許多強者推薦 mitmproxy (MITM 是 man-in-the-middle 的意思), 試用了一下的確超好用的。它用 man-in-the-middle attack 的方式觀察 (甚至更改) HTTP/HTTPS 傳輸的內容。
How To: Use mitmproxy to read and modify HTTPS traffic 介紹原理和用法, 設定很簡單。
官方文件也很清楚, 可交叉參考:
這裡摘要一下 mitmproxy 作為 Transparent Proxy 的方式和原理:
我是用 ASUS Zenfone 2, 不過 App 的測試結果應該和手機無關。
結果如下:
這些也是很有名的 Web Proxy, 有看到朋友推薦。不確定作為 transparent proxy 的效果如何, 至少監控本機的訊息應該滿方便的, 留著備忘。
聽 Scott 提到可用 Certificate Pinning 防 MITM attack。原理是只相信自己指定的 certificate (或幫你簽 certificate 的 certificate), 這樣就會忽視攻擊者裝到作業系統的 root CA。當 SSL handshake 的 certificate 被替換的時候, 會變成 handshake error。Certificate Pinning 似乎有些不同的作法, 先記住關鍵字, 之後再來研究。
另一個好像可行但可能有問題的解法是不用 OS 提供的 certificate, 直接用自己包在 app 裡的 certificate (放 server 用的 certificate 或簽它的 CA 的 certificate, 意思一樣)。雖然這樣不用擔心裝置被裝了有問題的 root certificate, 但和 self-signed certificate 一樣, 需要處理另一個問題 (原本的問題): 如何確定 app 內裝了正確的 certificate? 這個難題原本是由 OS 處理, 假設 OS 沒安裝有問題的 root certificate, 所以可以用它的 root certificate。
經 Victor 告知, 發現 Gmail 應該有檢查 certificate, 我又測了一下, 並更正內文。
Gmail 和 Google Play 有檢查 certificate, 只是使用者從系統刪除信任的 certificate 時, app 沒有同步更新, 仍會相信這個 certificate。另一方面, Chrome 有同步更新。
為了節省 HTTP response 的傳輸量, HTTP 有提供 request header Accept-Encoding: gzip 要求 server 「可以的話, 用 gzip 壓縮 body 再傳回來」, 還有 response header Content-Encoding: gzip 告知 client 「response body 有用 gzip 壓縮」。
在這樣的規定下, 推測 HTTP library 可能會有兩種實作方式:
不過實際情況是:
結果只有 Android 的實作符合預期。使用前還是要先測過才準啊。
附帶一提, http://httpbin.org/ 會回傳 request/response header, 用來測試 HTTP library 很方便。或是用 mitmproxy 作 transparent proxy 也可以, 相對之下費工一點, 不過看得最清楚。
Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...