Plan 9カーネルにおけるTCP/IP実装(未完)

15
Plan 9カーネルにおける TCP/IP実装(未完) oraccha Plan9日記(http://d.hatena.ne.jp/oraccha/2010331

Transcript of Plan 9カーネルにおけるTCP/IP実装(未完)

Page 1: Plan 9カーネルにおけるTCP/IP実装(未完)

Plan 9カーネルにおけるTCP/IP実装(未完)

oracchaPlan9日記(http://d.hatena.ne.jp/oraccha/)

2010年3月31日

Page 2: Plan 9カーネルにおけるTCP/IP実装(未完)

/net

• ネットワークもファイルとして抽象化net

ether0 tcp udp cs dns

clone stats0 1

listenerrdatactl local remote status

デバイス プロトコルスタック サービス

Page 3: Plan 9カーネルにおけるTCP/IP実装(未完)

デバイスドライバ• #から始まる名前を持つ特殊ファイル• NW関連は/net以下の名前空間にbind

% ns

:

bind -a '#l' /net

bind -a '#I' /net

イーサネット(/net/ether)

IP(/net/ipifc,arp,icmp,udp,tcp,...)

Page 4: Plan 9カーネルにおけるTCP/IP実装(未完)

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

Page 5: Plan 9カーネルにおけるTCP/IP実装(未完)

QueueとBlock• struct Queue:

• 送受信キューの実装で利用• Blockのリストを保持

• struct Block:

• BSDのmbufやLinuxのsk_buffに相当

• Blockは最大64KBのデータを格納可能

Page 6: Plan 9カーネルにおけるTCP/IP実装(未完)

write (port/sysfile.c)

• fdtochan関数でfdからChan *cを取得

• devtab[c->type]->writeを実行

*fgrp **fd type &etherdevtab

&ipdevtab

Proc Fgrp Chan Dev devtab[]

‘l’“IP”

(*write)()

注:devtab[]はビルド時に自動生成される

Page 7: Plan 9カーネルにおけるTCP/IP実装(未完)

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 */};

Page 8: Plan 9カーネルにおけるTCP/IP実装(未完)

“tcp”IP_TCPPROTO

*f

プロトコルの初期化• namec関数からipattach関数の呼出し

• Fsを初期化し、ipprotoinit[]の関数群(e.g. tcpinit関数)を実行

dev

*p[]*t2p[]

Fs *ipfs[Nfs] Fs Proto

IP_TCPPROTO

dev

注:ipprotoinit[]はビルド時に自動生成される

Page 9: Plan 9カーネルにおけるTCP/IP実装(未完)

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);}

Page 10: Plan 9カーネルにおけるTCP/IP実装(未完)

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

Page 11: Plan 9カーネルにおけるTCP/IP実装(未完)

update:スコアボード管理• Tcpctl: TCP制御ブロック(TCB)

• ウィンドウ制御• cwnd: 輻輳ウィンドウ

• window: 受信ウィンドウ

• Limbo: listenerキュー管理

Page 12: Plan 9カーネルにおけるTCP/IP実装(未完)

輻輳制御

• TCPの肝

• Renoかと思いきやTahoeっぽい

• 高速リカバリしない• Window scaling optionはデフォルト無効

Page 13: Plan 9カーネルにおけるTCP/IP実装(未完)

タイマ管理• tcpackproc(#I0tcpack)スレッド

• 50ミリ秒ごとに起床し、各タイマのexpireをチェック

• タイマハンドラ• tcb->timer: tcptimeout

• tcb->acktimer: tcpacktimer

• tcb->katimer: tcpkeepalive

• tcb->rtt_timer: RTT推定に使用

Page 14: Plan 9カーネルにおけるTCP/IP実装(未完)

その他

• ストリーム毎の統計情報が取得可能• /net/tcp/*/state

• IPv4アドレスもIPv4-mapped IPv6アドレスで内部的に処理

Page 15: Plan 9カーネルにおけるTCP/IP実装(未完)

qid

• ファイルサーバ単位のファイル識別子• UNIXのinodeに相当