Plan 9カーネルにおけるTCP/IP実装(未完)
-
Upload
ryousei-takano -
Category
Technology
-
view
1.862 -
download
7
Transcript of Plan 9カーネルにおけるTCP/IP実装(未完)
Plan 9カーネルにおけるTCP/IP実装(未完)
oracchaPlan9日記(http://d.hatena.ne.jp/oraccha/)
2010年3月31日
/net
• ネットワークもファイルとして抽象化net
ether0 tcp udp cs dns
clone stats0 1
listenerrdatactl local remote status
デバイス プロトコルスタック サービス
デバイスドライバ• #から始まる名前を持つ特殊ファイル• NW関連は/net以下の名前空間にbind
% ns
:
bind -a '#l' /net
bind -a '#I' /net
イーサネット(/net/ether)
IP(/net/ipifc,arp,icmp,udp,tcp,...)
ipwriteip/devip.c
tcpkicktcpoutput
transmit
ipoput4
etherbwrite
ipread
tcpiput
interrupt
ipiput4
etherread4
ip/tcp.c
ip/ip.c
ip/ethermedium.c
etheriq
etherbwriteetheroqpc/devether.c
pc/etherxxxx.c
write(2) read(2)
wq rq
in
oq
QueueとBlock• struct Queue:
• 送受信キューの実装で利用• Blockのリストを保持
• struct Block:
• BSDのmbufやLinuxのsk_buffに相当
• Blockは最大64KBのデータを格納可能
write (port/sysfile.c)
• fdtochan関数でfdからChan *cを取得
• devtab[c->type]->writeを実行
*fgrp **fd type ðerdevtab
&ipdevtab
Proc Fgrp Chan Dev devtab[]
‘l’“IP”
(*write)()
注:devtab[]はビルド時に自動生成される
Dev ipdevtab = { 'I', /* dc */ "ip", /* name */
ipreset, /* reset */ devinit, /* init [Do nothing] */ devshutdown, /* shutdown [Do nothing] */ ipattach, /* attach */ ipwalk, /* walk */ ipstat, /* stat */ ipopen, /* open */ ipcreate, /* create [Eperm] */ ipclose, /* close */ ipread, /* read */ ipbread, /* block read */ ipwrite, /* write */ ipbwrite, /* block write */ ipremove, /* remove [Eperm] */ ipwstat, /* wstat */};
“tcp”IP_TCPPROTO
*f
プロトコルの初期化• namec関数からipattach関数の呼出し
• Fsを初期化し、ipprotoinit[]の関数群(e.g. tcpinit関数)を実行
dev
*p[]*t2p[]
Fs *ipfs[Nfs] Fs Proto
IP_TCPPROTO
dev
注:ipprotoinit[]はビルド時に自動生成される
void tcpinit(Fs *fs) { Proto *tcp; Tcppriv *tpriv; tcp = smalloc(sizeof(Proto)); tpriv = tcp->priv = smalloc(sizeof(Tcppriv)); tcp->name = "tcp"; tcp->connect = tcpconnect; tcp->announce = tcpannounce; tcp->ctl = tcpctl; tcp->state = tcpstate; tcp->create = tcpcreate; tcp->close = tcpclose; tcp->rcv = tcpiput; tcp->advise = tcpadvise; tcp->stats = tcpstats; tcp->inuse = tcpinuse; tcp->gc = tcpgc; tcp->ipproto = IP_TCPPROTO; tcp->nc = scalednconv(); tcp->ptclsize = sizeof(Tcpctl); tpriv->stats[MaxConn] = tcp->nc; Fsproto(fs, tcp);}
Closed
Listen
Syn_received
Established
Finwait1
Finwait2
Closing
Time_wait
Syn_sent
Close_wait
Last_ack
appl: listen()
recv: SYNsend: SYN, ACK
recv: ACK recv: SYN, ACKsend: ACK
recv: SYNsend: SYN, ACK
appl: connect()send: SYN
※一部の状態遷移は省略
recv: FINsend: ACK
appl: close()send: FIN
recv: ACK2MSL timeoutrecv: FINsend: ACK
recv: ACK recv: ACK
recv: FINsend: ACK
recv: FIN, ACKsend: ACK
active open
active close
passive open
passive close
update:スコアボード管理• Tcpctl: TCP制御ブロック(TCB)
• ウィンドウ制御• cwnd: 輻輳ウィンドウ
• window: 受信ウィンドウ
• Limbo: listenerキュー管理
輻輳制御
• TCPの肝
• Renoかと思いきやTahoeっぽい
• 高速リカバリしない• Window scaling optionはデフォルト無効
タイマ管理• tcpackproc(#I0tcpack)スレッド
• 50ミリ秒ごとに起床し、各タイマのexpireをチェック
• タイマハンドラ• tcb->timer: tcptimeout
• tcb->acktimer: tcpacktimer
• tcb->katimer: tcpkeepalive
• tcb->rtt_timer: RTT推定に使用
その他
• ストリーム毎の統計情報が取得可能• /net/tcp/*/state
• IPv4アドレスもIPv4-mapped IPv6アドレスで内部的に処理
qid
• ファイルサーバ単位のファイル識別子• UNIXのinodeに相当