2014年11月24日 星期一

檔案切割

用 split 切割檔案
split -d -b 1G big.file big.file.

合併檔案
cat big.file.* > big.file

參考來源
  1. http://stackoverflow.com/questions/1120095/split-files-using-tar-gz-zip-or-bzip2
延伸閱讀
  • 用 dd 應該也可以

NAT 及 RTP proxy

RTP 封包無法直接送給 NAT 後面的 UA,需要知道 NAT 使用的 port。
  1. UA1 送 RTP 封包給 RTP Proxy (在 NAT1 開了通訊埠),但不知如何往 NAT2 哪個通訊埠送。
  2. UA2 送 RTP 封包給 RTP Proxy (在 NAT2 開了通訊埠),送給 NAT1 的通訊埠,再轉給 UA1
  3. RTP Proxy 已知道 NAT2 的通訊埠 , 將 UA1 的 RTP 封包送給 NAT2 的通訊埠,再轉給 UA2
如何避免 RTP proxy?

2014年11月21日 星期五

kamailio

沿革

Kamailio 是 GPL 開源的 SIP 伺服器,一開始叫作 SIP Express Router (SER),2005 另外分出為 OpenSER,2008 因商標問題改名為 kamailio (夏威夷話的談話、通話),不久後合併老東家 SER,之後釋出的第一個兩者相容版本是 v3.0.0。2014 三月釋出 v4.0.0,真正將兩者整合為一,並支援 WebSocket。

2017/02/27:釋出 v5.0.0

kamailio 跟 Asterisk 的不同

SIP 而言,他們的差別就是 SIP Proxy 跟 SIP PBX 的不同。在 SIP PBX,通話的兩端是分別跟 SIP PBX 通,SIP PBX 再把兩端搭起來,SIP PBX 等於是背對背的網路話機 (b2bua)。這個背對背的兩個網路話機之間可以做很多應用,例如錄音、DTMF 轉換、送待機音樂、IVR、會議的混音、協定轉換等。而 SIP Proxy 只是「媒人」,幫忙通話的兩端「牽線」,兩端「來電」之後的發展就不是媒人的事了。雖然 SIP PBX 也可以作 SIP Proxy 使用,但就一通電話而言,其實是將相關的兩通電話搭起來,使用了較多的資源。

kamailio 使用入門

在 Ubuntu 使用 kamailio
kamailio 簡易命令檔 (簡易 SIP proxy,讓 SIP 話機註冊後互撥,不用建立帳號)
kamailio 命令檔說明 

kamailio 除錯

  • kamailio -c:測試設定檔,並列出監聽的網路界面
  • kamailio -E:顯示 strerr

kamailio 應用

transaction 支援:使用 tm 模組
  • t_relay
Proxy
Outbound proxy
Location server/registrar
  • 使用 registrar 模組搭配 usrloc 模組
  • registrar 模組的 save() 函數
  • registrar 模組的 lookup() 函數 [連結]
Presence server
SIP load balancer
  • 使用 dispatcher 模組:從檔案或資料庫讀取目的,依照 round-robin、weight based load balancing、call load distribution、hashing over SIP message attributes 等規則轉送。
Call routing (Least Cost Routing)
Application server
SIP session border controller

使用資料庫
使用其它程式語言

參考來源

  1. http://www.slideshare.net/oej/kamailio-a-quick-introduction
  2. http://kamailio.org/docs/ser-getting-started/SER-GettingStarted.pdf
  3. http://www.kamailio.org/wiki/cookbooks/4.2.x/core
  4. http://kamailio.org/docs/modules/stable/

延伸閱讀

  • SIP Routing Done In Lua with Kamailio
  • /etc/kamailio/kamctlrc:kamdbctl 或 kamctl 用到的參數
  • kamctl MI (management interface) 可 start/stop、shared variables、建立 SIP 帳號、statistics
  • kamdbctl:建立資料庫
  • kamcmd:RPC 界面及 MI 功能、Select/Config variables、statistics
  • siremis:Web application、database 管理、statistics
  • kamialio 管理界面:MI、RPC、pipe、Json、XMLrpc
  • kamailio 4.2.x:corepseudo variables、及 transformation
  • kamailio 模組
    • dialplan:比對轉換規則
    • dmq:distributed message queue, 可跟其它 kamailio 間傳遞訊息,基於這個機制可發展其他應用,如 dmq_usrloc 跟 htable 用來同步資料。
    • exec: 透過環境變數 SIP_xxx 傳遞額外資訊來執行 shell 指令。
      • exec_dset(command):每行輸出成為 destination set
      • exec_msg(command)
      • exec_avp(command [, avplist]):每行輸出存為 avp
    • p_usrloc:使用多個位置資料庫
    • outbound
    • memcached:提供 pseudo-variables $mct(key), $mct(key=>expiry), $mcinc(key), $mcdec(key), $mctex(key) 存取外部伺服器程式 memcached 管理、存在記憶體的 distributed hash table。expire 或空間不足
    • rr:
      • loose_route
    • usrloc:

2014年11月11日 星期二

tcpdump

tcpdump 透過 libpcap,使用 kernel 裡或 userspace 的 BPF 虛擬機器進行封包擷取工作,並將封包加以解釋後輸出。

指令格式
tcpdump [參數] [過濾表示式]
其中參數以「-」開頭,可能接著參數值,剩下的為過濾表示式。

執行 tcpdump,網卡原本只收 MAC 定址符合和廣播的封包,會進入 "promiscuous" 模式改接收所有的封包,處理額外的封包會用掉一些處理器效能。

參數

  • -s0:擷取整個封包,而不是只有前 68 byte。
  • -n:不解析主機名稱、MAC 位址,可加快處理,避免錯過封包。
  • -i:指定要等待的網卡界面
  • -w:結果存到 pcap 檔 
  • -d: 
  • -dd:
  • -ddd:
範例
  • tcpdump # 全抓
  • tcpdump -i eth0
  • tcpdump -r in.pcap #讀取檔案
  • tcpdump -i eth0 -G 3600 -w 'file.pcap' # 每小時 rotating
  • tcpdump -i eth0 -C 100 -w capture # 每 100MB 換檔案
  • tcpdump -s0 -n -i ethX -w /tmp/$(hostname)-$(date +"%Y-%m-%d-%H-%M-%S").pcap host <ip-address>
  • tcpdump 'udp port 20000 or (ip[6:2] & 0x1fff) != 0' # 抓 udp port 20000 和所有 fragment offset 不為 0 的封包 (有些 Linux 版本反順序傳送 IP fragments,讓最後 fragment 先收到而能更正確預測 reassembled 後的封包大小。)

遠端 tcpdump

參考

  1. BPF - the forgotten bytecode
測試網路連線
  • ping
  • traceroute 或 mtr
  • route -n 或 ip route
  • ip addr list 或 ifconfig
  • arp -an 或 cat /proc/net/arp
測試遠端通訊埠
  • nc (netcat)
  • wget 或 curl
  • nmap
檢查 link 狀態
  • dmesg | egrep “eth|em” 或 cat /var/log/messages
  • ip link show
  • mii-tool eth0 (deprecated , doesn't work on Gigabit NICs)
  • ethtool eth0 (net-tools 提供)
  • cat /sys/class/net/eth0/operstate
  • lsof (list open file)
查詢封包 loss
  • ifconfig
  • ethtool -S
    • 加大 buffer 大小:ethtool -g eth0 或 ethtool -G eth0 rx 4096
  • netstat -s
  • dropwatch
  • sar -n NDEV (每秒有多少錯)
調整 TCP socket buffer:/etc/sysctl.conf
  • net.ipv4.tcp_rmem = 4096 87380 4194304
  • net.ipv4.tcp_wmem = 4096 87380 4194304
socket 統計
  • ss -t -a:顯示所有 TCP socket
  • ss -it:socket 內部資訊
中斷負載平衡及 multiqueue:cat /proc/interrupts
offloading:ethtool -k eth0

2014年11月9日 星期日

pthread mutex

thread 程式有一個好處是全域變數在 process 內是共用的,不需要跨 process 共用機制,但存取時要避免衝突產生,其中一種方式是使用 mutex (mutual exclusion) 來建立 critical section,來同步共用資源的使用。

如果變數只是一個 int 且只有一個 thread 會改變它,其它都只是讀 => 沒有同步問題

mutex 只有兩種狀態:locked 及 unlocked。一個 mutex,只有一個 thread 可以取得 lock,此時只有它可以 unlock。其它 thread 要 lock 需等候。一般不能有下列行為:

  1. 一個 thread lock 同一個 mutex 兩次:可能產生 deadlock (Linux 預設) 或回傳錯誤碼 EDEADLK。
  2. 一個 thread unlock 不是它 lock 的 mutex
  3. 一個 thread unlock 還沒 lock 的 mutex
Mutex Deadlock: 有兩個以上的 mutex,當多個 thread 同時 lock 這些 mutex 時,由於 lock 哪個 mutex 的順序關係而造成 deadlock。

建立

mutex 是資料型態為 pthread_mutex_t 的變數,可以靜態或動態初始化:

靜態,初始化為 unlock。

pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;

動態初始化,可設 attr。如用預設值,attr 可為 NULL。不再使用時,應該要回到 unlocked 狀態後 destroy。

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);

成功時回傳 0 或正的錯誤碼。

pthread_mutexattr_init()
pthread_mutexattr_destroy()

Locking 和 Unlocking

pthread_mutex_lock(pthread_mutex_t *mutex):等候到 mutex unlock 後,lock 並馬上 return。

pthread_mutex_unlock(pthread_mutex_t *mutex):unlock 自己 thread 之前 lock 的 mutex。

另外還有兩種 lock 的變形
pthread_mutex_trylock():如果已經 lock,回 EBUSY。
pthread_mutex_timedlock():等候 abstime 還未取得 lock,回 ETIMEDOUT。

參考

  1. The Linux Programming Interface》chap. 30
  2. https://computing.llnl.gov/tutorials/pthreads/#Mutexes
  3. semaphore 也可以建立 critical section,但效能沒 mutex 好。
  4. 比較 pthread_spin_lock() (pthread_spin_trylock()):適合 lock 的時間極短 (例如只是計數加 1),很少發生 contention,常用到而有可能成為效能瓶頸。spinlock 無關乎 thread 切換,lock 失敗時 thread 不會造成 sleep,一可以取得時可以馬上取得 (前提是沒有 thread 切換,但是事實上需要另一個釋出 lock 的 thread,特別是 uni-processor,所以勢必忙於等待 thread 切換,反而可能等候更久)。unlock 時不會檢查其它 thread 是否在等待需喚醒,只是一個 atomic write instruction。
  5. pthread_cond_init()
  6. barrier
  7. pthread_rwlock_init():
    • Read lock 只要在沒有 Write lock 就可以,可有多個。
    • Write lock 要在沒有任何 Read 和 Write lock 下才可以,可能因為一直有新舊 Read lock 而導致 starvation。
  8. mutex 用在跨 process:mutex between processes

2014年11月2日 星期日

tftp

沿革
參考自 EFTP
1980 TFTP
1981 TFTP v2 (RFC 783)
1992 RFC 1350

Option Extension 1995 RFC 1782, 1998 RFC 2347
Blocksize Option

tftp 使用 UDP,預設傳送的資料大小是 512 octets。server listen UDP 69,client 首先發出讀或寫的請求 (WRQ 或 RRQ),server 自己選定一個 port 回覆資料或 ACK,接著 client 回覆 ACK 或資料,重複資料及 ACK 直到最後一筆資料大小小於選定的傳送資料大小。如有一端沒收到,則再重送。由於每送一筆資料後需要等候 ACK 後才能送下一筆資料,所以傳輸速度較慢。

沒有 list, delete, rename, directory, authentication 等進階功能

封包格式:
opcode + filename + mode
opcode + block # + data
opcode + block #
opcode + error code + error message

busybox tftp client
  • create_pkt:建立 WRQ/RRQ/ACK/DATA 封包
    • DATA 封包可能檔案讀取錯誤,送 error 後結束
    • 可能是要送最後 DATA 封包
  • send_pkt:初次送的 timeout 時間及嘗試次數初始化
  • send_again:送封包
    • 如果是送最後的 ACK,結束
  • recv_again:poll with timeout
    • ???,結束
    • timeout,如已達嘗試次數,結束;否則調整 timeout 時間再次 send_again
    • socket 讀取錯誤,送 error 後結束
    • 收到封包太短,recv_again
    • 收到 error,結束
    • get 收到 DATA 序號正確,檔案寫入錯誤的話送 error 後結束。可能是最後 DATA 封包。create_pkt
    • put 收到 ACK 序號正確,如果是收到最後的 ACK,結束;否則 create_pkt
    • 其它 recv_again

參考來源
  1. http://en.wikipedia.org/wiki/Trivial_File_Transfer_Protocol
  2. http://tools.ietf.org/html/rfc1350
  3. busybox tftp.c

SIP header Via

所有 SIP 訊息 都要有 Via,縮寫 v。一開始的 UAC 和後續途經的每個 proxy 都會疊加一個 Via 放傳送的位址,依序作為回應的路徑。 格式 sent-protocol sent-by [ ;branch= branch ][ ; 參數 ...] s...