蘋果小豬研究室
  • 首頁
  • 中譯資料
  • 網路觀念
    • OSGi 平台
    • SCTP 通訊協定簡介
      • 1 多重串流 (Multi-streaming)
      • 2 路徑多宿 (Multi-homing)
      • 3 SACK 機制
      • 4 Path MTU Discovery
      • 5 Ordered/Unordered 傳送機制
      • 6. SCTP API
      • 7. TCP 與 SCTP 通訊協定比較
      • 8. 參考文獻
    • TCP over SCTP tunnel
    • TCP 與 SCTP 協定轉換機制
    • UPnP 與 UPnP AV
  • Linux 程式設計
    • [C] 產生亂數
    • [C] Pointer and array
    • [Script] strncmp
    • [C] Linux 取得 HD 序號
    • [C] 程式範例-切割 subnet
    • C struct 的使用
    • C 目錄相關
    • const 修飾詞
    • Dangling pointer(懸置指標)
    • dnsmole
    • dos2unix 程式碼
    • Function pointer in C
    • GCC header limits.h
    • GDB 參數
    • glibc detected (double free)
    • IEEE 754 and float 範例程式
    • kernel 中的網路卡名稱與命名順序關係
    • Linux 序列埠程式設計
    • loop device 的數目
    • Perl & LWP
    • Remote Control over CGI
    • 偵測 NAT 內部主機連線狀況
    • 利用 libpcap 取得所有的網路裝置名稱
    • 取得時間
    • strncpy
    • 從應用層程式取得傳輸層 TCP 資訊
    • 於 Linux 上撰寫 daemon server 要注意的
    • 為什麼需要 & 0377
    • 研究 setsid()
    • 與 HTTP 協定有關的 RFC
    • 製作 patch 檔
    • 設計在背景執行的 Linux 程式
    • 讀取 STDIN (Standard INPUT) 範例程式
    • 關於 Linux CPU smp_affinity
    • 陣列名稱與指標
  • 網路服務推薦
    • 專案管理工具 - clickup
    • 文件大師 - gitbook
  • glibc 中文手冊
    • GNU C 函式庫常見問題(FAQ)
  • Linux 系統操作
    • /proc/sys/net/ipv4/conf/eth* 目錄中的參數
    • Linux 伺服器效能調校
    • Linux 設定網卡速度
    • Proxy ARP
    • sysrq
    • Turn off beep in Linux system
    • umask()
    • 以 ethtool 查看網路卡狀態及設定
    • 使用 nameif 修改 Linux 網路卡名稱
    • 使用 xhost
    • 利用 sed 取出檔案中某行
    • 在 bash 中設定 Proxy server
    • 在 Linux 系統呈現 dd 的進度
    • 字串取代,使用 awk & sed
    • 尋找多種副檔名
    • 常用 VIM 選項
    • 自動 CPU 調頻節能控制
    • 自動執行程式
    • 設定 Debian 預設啟動服務
    • 設定 DHCPd server
    • 透過 RS-232 操作 Linux console
    • Linux connect to serial port
  • 資訊安全
    • ARP spoofing 技術管控區網流量實例
    • dsniff
    • Linux Socket Filtering
    • Linux 系統安全管理
    • Security 資訊
    • sniffer 相關工具 - IPgrad, tcpick
    • 以 Linux 實務 ARP Spoofing
    • 將文字隱藏於 JPEG 圖檔
    • 資安工具
    • 資安相關網站
    • 限制 localhost 的 P2P 上傳流量
  • 實用工具
    • 實驗基本數據製圖指令 gnuplot
  • 交換連結
  • 網頁設定
  • 網路應用
    • 網路時光機
  • Foldng@Home
  • 文獻推薦
    • 電子書
    • 提問的智慧
    • 好書
  • 隱私政策
Powered by GitBook
On this page
Edit on GitHub
  1. Linux 程式設計

於 Linux 上撰寫 daemon server 要注意的

要撰寫一個網路伺服器 Deamon,一般要注意掌控 fork() 所產生的子行程 (child process) 數目,因此程式中需要記錄以對子行程的數目進行限制,以預防有人惡意的不斷送出僅設有 SYN flag 的 TCP SYN 封包(packet),導致 TCP 三向交握(Three-way handshaking)無法正常完成,而 Daemon 只能不斷停留在等待 SYN-ACK,最後耗盡系統資源,導致系統完全當機(crash)。 ulimit -Ha 與 ulimit -Sa 來檢視目前系統的硬限制(Hard limit)與軟限制(Soft limit) 的值:

# ulimit -Sa core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) unlimited virtual memory (kbytes, -v) unlimited # ulimit -Ha core file size (blocks, -c) unlimited data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 stack size (kbytes, -s) unlimited cpu time (seconds, -t) unlimited max user processes (-u) unlimited virtual memory (kbytes, -v) unlimited

根據 man bash 對 ulimit hard limit 與 soft limit 的描述,他們的功用在於,hard limit 一旦設定之後就無法在增加該參數的值,而 soft limit 則是最多可以增加到與 hard limit 的值一樣多,還有就是 hard limit 是需要管理員權限(super user)才能更動的。 像上例,就有個很明顯的 open files,這個項目的值就表示 Linux 預設一個行程可開啟的 file descriptor 數目是 1024 個,如果我們沒有更改這個值,那我們的程式最多只能開啟 1024 個檔案而已。 除了檔案,由於 Linux 中開啟某裝置都是抽象化分層了,於是像開啟某個檔案一般,開啟的 socket 連線數也是受制於檔案的開啟數目,所以如果要讓 server 可以接受大於 1024 的連線,則需要修改這個值。 有幾個系統呼叫 (system call),可以寫在程式中更動這些預設值: ulimit()、getrlimit()/setrlimit(),其中後兩者是用來取代 ulimit() 的。 下列是 getrlimit/setrlimit 系統呼叫的函式原型(prototype):

int getrlimit(int resource, struct rlimit); int setrlimit(int resource, const struct rlimit *rlim);

其中 resource 是所要更動的項目選項,如我們想更動可開啟檔案的個數,則可修改 RLIMIT_NOFILE,如 setrlimit( RLIMIT_NOFILE, &rlim); Man manual for details: $ man 2 getrlimit $ man 2 setrlimit 細節可參考 manual: $ man 2 getrlimit $ man 2 setrlimit 下列為 rlimit 的 structure: struct rlimit{ rlimit_t rlimit_cur; // Soft-limit rlimit_t rlim_max; // Hard-limit }; 下面用一個簡單的範例,來呈現如何使用 getrlimit/setrlimit 取得與設定,這個範例,首先會用 getrlimit 取得目前可開啟檔案的 soft limit 與 hard limit,然後,再用 setrlimit 設定希望的值,最後再用 getrlimit 重新取得一次確認修改結果。

// test.cpp
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <iostream>

using namespace std;

int main(void)
{
  struct rlimit limit;
  const struct rlimit mit = { 2048, 600000 };

  getrlimit(RLIMIT_NOFILE, &limit);
  cout << "Current: " << limit.rlim_cur << endl;
  cout << "Max: " << limit.rlim_max << endl;

  setrlimit(RLIMIT_NOFILE, &mit);

  getrlimit(RLIMIT_NOFILE, &limit);
  cout << "Current: " << limit.rlim_cur << endl;
  cout << "Max: " << limit.rlim_max << endl;

  return 0;
}

編譯:

g++ test.cpp -o test

執行結果:

# ./test Current: 1024 Max: 1024 Current: 2048 Max: 600000

Previous從應用層程式取得傳輸層 TCP 資訊Next為什麼需要 & 0377

Last updated 2 years ago

除了 RLIMIT_NOFILE,其他還有如 RLIMIT_NPROC (最大行程數目)、RLIMIT_FSIZE (最大檔案大小)等都是需要注意的項目,關於 resource 的完整選項可以在 Linux /usr/include/bits/resource.h 找到。 還有一個可查詢目前系統限制的函式,sysconf(int name) 比如可以使用 sysconf( _SC_OPEN_MAX ) 來查詢目前可開啟的最大檔案個數,細節請 man 3 sysconf,完整的參數有上百個,一樣是可以在 /usr/include/bits/confname.h 找到。 Client 的部份則是要注意 connect timeout 問題,TCP sender 要注意 sned() 之傳回值,send 與 recv 可配合 select() 使用。 PS: 設定 limit 雖然可以避免資源被耗盡,但是,該 sshd 服務等同於受到阻斷式攻擊,導致其他使用者無法連線,該怎麼辦呢? 參考文獻: John Shapley Gray, , Chap 2.9, Pearson Education, 2003.

Interprocess Communications in Linux: The Nooks and Crannies