Changeset 318 for asp3_gr_sakura/trunk/tinet/netinet/tcp_input.c
- Timestamp:
- Aug 3, 2017, 10:46:41 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
asp3_gr_sakura/trunk/tinet/netinet/tcp_input.c
- Property svn:keywords deleted
-
Property svn:mime-type
changed from
text/x-csrc
totext/x-csrc; charset=UTF-8
r317 r318 5 5 * Tomakomai National College of Technology, JAPAN 6 6 * 7 * ä¸è¨èä½æ¨©è 8 ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 9 * ã«ãã£ã¦å 10 ¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨ 11 * è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢ 12 * ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ã使ç¨ã»è¤è£½ã»æ¹å¤ã»åé 13 å¸ï¼ä»¥ä¸ï¼ 14 * å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼ 15 * (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½ 16 * 権表示ï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼ 17 * ã¹ã³ã¼ãä¸ã«å«ã¾ãã¦ãããã¨ï¼ 18 * (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿ 19 * ç¨ã§ããå½¢ã§åé 20 å¸ããå ´åã«ã¯ï¼åé 21 å¸ã«ä¼´ãããã¥ã¡ã³ãï¼å©ç¨ 22 * è 23 ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ 24 * ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼ 25 * (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿ 26 * ç¨ã§ããªãå½¢ã§åé 27 å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼ 28 * (a) åé 29 å¸ã«ä¼´ãããã¥ã¡ã³ãï¼å©ç¨è 30 ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è 31 * ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼ 32 * (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ 33 * 害ãããï¼ä¸è¨èä½æ¨©è 34 ããã³TOPPERSããã¸ã§ã¯ããå 35 責ãããã¨ï¼ 7 * 上記著作権者は,以下の (1)~(4) の条件か,Free Software Foundation 8 * によって公表されている GNU General Public License の Version 2 に記 9 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア 10 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下, 11 * 利用と呼ぶ)することを無償で許諾する. 12 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 13 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー 14 * スコード中に含まれていること. 15 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 16 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 17 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 18 * の無保証規定を掲載すること. 19 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 20 * 用できない形で再配布する場合には,次の条件を満たすこと. 21 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 22 * 作権表示,この利用条件および下記の無保証規定を掲載すること. 23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. 36 25 * 37 * æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è 38 ã 39 * ãã³TOPPERSããã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã 40 * å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´ 41 * æ¥çã¾ãã¯éæ¥çã«çãããããªãæ害ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼ 26 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お 27 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も 28 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直 29 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない. 42 30 * 43 31 * @(#) $Id$ … … 128 116 129 117 /* 130 * æ»ãå¤118 * 戻り値 131 119 * 132 * RET_OK æ£å¸¸133 * RET_DROP ã¨ã©ã¼ãã»ã°ã¡ã³ããç ´æ£ããã134 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã120 * RET_OK 正常 121 * RET_DROP エラー、セグメントを破棄する。 122 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 135 123 */ 136 124 … … 142 130 143 131 /* 144 * é¢æ°132 * 関数 145 133 */ 146 134 … … 159 147 160 148 /* 161 * parse_option -- TCP ãããã®ãªãã·ã§ã³ã解æããã149 * parse_option -- TCP ヘッダのオプションを解析する。 162 150 */ 163 151 … … 214 202 215 203 /* 216 * set_rexmt_timer -- æ°ããå¾å¾©æéãåéããåéã¿ã¤ããæ´æ°ããã204 * set_rexmt_timer -- 新しい往復時間を収集し、再送タイマを更新する。 217 205 */ 218 206 … … 225 213 if (cep->srtt != 0) { 226 214 /* 227 * srtt: å¹³æ»åãããRTT215 * srtt: 平滑化された RTT 228 216 * 229 * è¨æ¸¬ããã RTT (rtt) ã¨ç¾å¨ã®å¹³æ»åããã RTT (srtt) ã®å·® (delta) ãæ±ããã217 * 計測された RTT (rtt) と現在の平滑化された RTT (srtt) の差 (delta) を求める。 230 218 * 231 * delta 㯠2 ãããå·¦ã·ãã ( 4 å) ããå¤ã§ä¿æããã232 * srtt 㯠5 ãããå·¦ã·ãã (32 å) ããå¤ã§ä¿æããã¦ããã219 * delta は 2 ビット左シフト ( 4 倍) した値で保持する。 220 * srtt は 5 ビット左シフト (32 倍) した値で保持されている。 233 221 * 234 222 * delta = rtt / 8 - srtt / 8 235 223 * 236 * æ°ãã srtt ã¯224 * 新しい srtt は 237 225 * 238 226 * srtt = rtt / 8 + srtt * 7 / 8 239 227 * = srtt + (rtt / 8 - srtt / 8) 240 228 * 241 * ã§è¨ç®ããã242 * ãã®ãããrtt ã 2 ãããå·¦ã·ããããsrtt ã (5 - 2) ãããå³ã·ããã㦠delta ãæ±ããã229 * で計算する。 230 * このため、rtt を 2 ビット左シフトし、srtt を (5 - 2) ビット右シフトして delta を求める。 243 231 */ 244 232 delta = ((rtt - 1) << TCP_DELTA_SHIFT) - (cep->srtt >> (TCP_SRTT_SHIFT - TCP_DELTA_SHIFT)); … … 248 236 249 237 /* 250 * delta ã®çµ¶å¯¾å¤ | delta | ãæ±ããã238 * delta の絶対値 | delta | を求める。 251 239 */ 252 240 if (delta < 0) … … 254 242 255 243 /* 256 * rttvar: å¹³æ»åãããåæ£244 * rttvar: 平滑化された分散 257 245 * 258 * rttvar 㯠4 ãããå·¦ã·ãã (16 å) ããå¤ã§ä¿æããã¦ããã246 * rttvar は 4 ビット左シフト (16 倍) した値で保持されている。 259 247 * 260 248 * delta = |delta| / 4 - rttvar / 4 261 249 * 262 * æ°ãã rttvar ã¯250 * 新しい rttvar は 263 251 * 264 252 * rttvar = |delta|/ 4 + rttvar * 3 /4 265 253 * = rttvar + (|delta| / 4 - rttvar / 4) 266 254 * 267 * ã§è¨ç®ããã255 * で計算する。 268 256 */ 269 257 delta -= cep->rttvar >> (TCP_RTTVAR_SHIFT - TCP_DELTA_SHIFT); … … 274 262 else { 275 263 /* 276 * ã¾ã srtt ã®è¨å®ãè¡ããã¦ããªãã¨ãã¯ãä»åè¨æ¸¬ããã RTT ã使ç¨ããã277 * å¹³æ»åããã RTT (srtt) ã«ã¯ãRTT ã 5 ãããå·¦ã·ãã (32å) ããå¤ã278 * å¹³æ»åãããåæ£ (rttvar) ã«ã¯ãRTT ã® 1/2 ã 4 ãããå·¦ã·ãã (16å) ããå¤ã264 * まだ srtt の設定が行われていないときは、今回計測された RTT を使用する。 265 * 平滑化された RTT (srtt) には、RTT を 5 ビット左シフト (32倍) した値。 266 * 平滑化された分散 (rttvar) には、RTT の 1/2 を 4 ビット左シフト (16倍) した値。 279 267 */ 280 268 cep->srtt = rtt << TCP_SRTT_SHIFT; … … 283 271 284 272 /* 285 * rtt ã®æ¸¬å®ãçµäºããåéåæ°ããªã»ããããã273 * rtt の測定を終了し、再送回数をリセットする。 286 274 */ 287 275 cep->rtt = cep->rxtshift = 0; 288 276 289 277 /* 290 * RTT ã«è¨±ãããæå°å¤ 㨠rtt + 2 ã®å¤§ããªå¤ã®æ¹ãåéã¿ã¤ã ã¢ã¦ãã®æå°å¤ã«ããã278 * RTT に許される最小値 と rtt + 2 の大きな値の方を再送タイムアウトの最小値にする。 291 279 */ 292 280 if (rtt + 2 < TCP_TVAL_MIN) … … 301 289 302 290 /* 303 * reassemble -- åä¿¡ã»ã°ã¡ã³ããåæ§æãããé çªéãã«åä¿¡ããã¨ãã®å¦ç291 * reassemble -- 受信セグメントを再構成する。順番通りに受信したときの処理 304 292 */ 305 293 … … 313 301 if (tcph->sum > cep->rbufsz - cep->rwbuf_count) { 314 302 /* 315 * åä¿¡ã¦ã£ã³ããããã¡ã«ç©ºãããªãã¨ãã¯ç ´æ£ããã303 * 受信ウィンドバッファに空きがないときは破棄する。 316 304 */ 317 305 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_DROP_SEGS], 1); … … 324 312 cep->fsm_state == TCP_FSM_ESTABLISHED) { 325 313 /* 326 * é çªéãã«ã»ã°ã¡ã³ããåä¿¡ããæã®å¦ç327 * åä¿¡ã»ã°ã¡ã³ãã®ä¸¦ã¹æ¿ãã¯ä¸è¦ãªã®ã§328 * ãã®ã¾ã¾åä¿¡ã¦ã£ã³ããããã¡ã«æ¸ãè¾¼ãã314 * 順番通りにセグメントを受信した時の処理 315 * 受信セグメントの並べ替えは不要なので 316 * そのまま受信ウィンドバッファに書き込む。 329 317 */ 330 318 … … 341 329 qhdr = GET_TCP_Q_HDR(input, thoff); 342 330 343 /* TCP ãããã®ä½ç½®ãä¿åããã*/331 /* TCP ヘッダの位置を保存する。*/ 344 332 SET_IP_TCP_Q_HDR_OFFSET(input, thoff); 345 333 346 /* SDU ã®ãªãã»ããï¼å 347 ã¯ã¦ã£ã³ããµã¤ãºï¼ããªã»ããããã*/ 334 /* SDU のオフセット(元はウィンドサイズ)をリセットする。*/ 348 335 qhdr->soff = 0; 349 336 350 /* ãã¼ã¿ãåä¿¡ã¦ã£ã³ããããã¡ã«æ¸ãè¾¼ãã*/337 /* データを受信ウィンドバッファに書き込む。*/ 351 338 TCP_WRITE_RWBUF(cep, input, thoff); 352 339 } … … 359 346 360 347 /* 361 * listening -- ååãªã¼ãã³ãã¦ï¼ç¶æ 362 ã LISTEN ã®å¦ç 348 * listening -- 受動オープンして,状態が LISTEN の処理 363 349 * 364 * æ»ãå¤:365 * RET_OK æ£å¸¸366 * RET_DROP ã¨ã©ã¼ãã»ã°ã¡ã³ããç ´æ£ããã367 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã350 * 戻り値: 351 * RET_OK 正常 352 * RET_DROP エラー、セグメントを破棄する。 353 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 368 354 */ 369 355 … … 376 362 377 363 /* 378 * ãã©ã°ã« RST ãã»ããããã¦ããã°ç ´æ£ããã364 * フラグに RST がセットされていれば破棄する。 379 365 */ 380 366 if (tcph->flags & TCP_FLG_RST) … … 382 368 383 369 /* 384 * ãã©ã°ã« ACK ãã»ãããã¦ãããã°ã385 * ãªã»ãããéã£ã¦ç ´æ£ããã370 * フラグに ACK がセットさてれいれば、 371 * リセットを送って破棄する。 386 372 */ 387 373 if (tcph->flags & TCP_FLG_ACK) … … 389 375 390 376 /* 391 * ãã©ã°ã« SYN ãã»ããããã¦ããªããã°ãã°ç ´æ£ããã377 * フラグに SYN がセットされていなければれば破棄する。 392 378 */ 393 379 if ((tcph->flags & TCP_FLG_SYN) == 0) … … 395 381 396 382 /* 397 * åä¿¡å¯è½ãª IP ã¢ãã¬ã¹ã¨ãã¼ãçªå·ã§ãããã¨ã確èªããã383 * 受信可能な IP アドレスとポート番号であることを確認する。 398 384 */ 399 385 if (!tcp_is_addr_accept(input, thoff)) 400 386 return RET_DROP; 401 387 402 /* ç¸æã®ã¢ãã¬ã¹ãè¨é²ããã*/388 /* 相手のアドレスを記録する。*/ 403 389 IN_COPY_TO_HOST(&cep->dstaddr.ipaddr, input); 404 390 cep->dstaddr.portno = tcph->sport; 405 391 406 /* ãªãã·ã§ã³ãå¦çããã*/392 /* オプションを処理する。*/ 407 393 parse_option(tcph, cep); 408 394 409 /* ã·ã¼ã±ã³ã¹çªå·ãåæåããã*/395 /* シーケンス番号を初期化する。*/ 410 396 if (tcp_iss == 0) 411 397 tcp_init_iss(); 412 398 413 /* èªåã®ã·ã¼ã±ã³ã¹çªå·ã®åæå¤ãè¨é²ããã*/399 /* 自分のシーケンス番号の初期値を記録する。*/ 414 400 if (iss != 0) 415 401 cep->iss = iss; … … 419 405 tcp_iss += TCP_ISS_INCR() / 4; 420 406 421 /* ç¸æã®ã·ã¼ã±ã³ã¹çªå·ã®åæå¤ãè¨é²ããã*/407 /* 相手のシーケンス番号の初期値を記録する。*/ 422 408 cep->irs = tcph->seq; 423 409 424 /* éåä¿¡ã·ã¼ã±ã³ã¹çªå·ãåæåããã*/410 /* 送受信シーケンス番号を初期化する。*/ 425 411 init_send_seq(cep); 426 412 init_receive_seq(cep); 427 413 428 /* éä¿¡ã¦ã¤ã³ããµã¤ãºãè¨å®ããã*/414 /* 送信ウインドサイズを設定する。*/ 429 415 cep->snd_wnd = tcph->win; 430 416 431 /* æçµè¨å®*/417 /* 最終設定 */ 432 418 cep->flags |= TCP_CEP_FLG_ACK_NOW; 433 419 cep->fsm_state = TCP_FSM_SYN_RECVD; … … 438 424 439 425 /* 440 * syn_sent -- è½åãªã¼ãã³ãã¦ãç¶æ 441 ã SYN éä¿¡æ¸ã®å¦ç 426 * syn_sent -- 能動オープンして、状態が SYN 送信済の処理 442 427 * 443 * æ»ãå¤:444 * RET_OK æ£å¸¸445 * RET_DROP ã¨ã©ã¼ãã»ã°ã¡ã³ããç ´æ£ããã446 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã428 * 戻り値: 429 * RET_OK 正常 430 * RET_DROP エラー、セグメントを破棄する。 431 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 447 432 */ 448 433 … … 453 438 454 439 /* 455 * ç¸æããå信確èªãéããã¦æ¥ã¦ãã440 * 相手から受信確認が送られて来ても、 456 441 * 457 * ACK <= iss && éä¿¡ããæ大SEQ (snd_max) < ACK442 * ACK <= iss && 送信した最大 SEQ (snd_max) < ACK 458 443 * 459 * ãªãããªã»ãããéã£ã¦ã»ã°ã¡ã³ããç ´æ£ããã444 * なら、リセットを送ってセグメントを破棄する。 460 445 */ 461 446 if ((tcph->flags & TCP_FLG_ACK) && … … 464 449 465 450 /* 466 * RST/ACK ãã©ã°ã®å¿çãããã°ããã¼ããéãã¦ããªã467 * ãã¨ãæå³ãã¦ããã451 * RST/ACK フラグの応答があれば、ポートが開いていない 452 * ことを意味している。 468 453 */ 469 454 if (tcph->flags & TCP_FLG_RST) { … … 476 461 477 462 /* 478 * SYN ãã©ã°ããªããã°ã»ã°ã¡ã³ããç ´æ£ããã463 * SYN フラグがなければセグメントを破棄する。 479 464 */ 480 465 if ((tcph->flags & TCP_FLG_SYN) == 0) 481 466 return RET_DROP; 482 467 483 cep->snd_wnd = tcph->win; /* snd_wnd: ç¸æã®åä¿¡å¯è½ã¦ã£ã³ããµã¤ãº*/484 cep->irs = tcph->seq; /* irs: ç¸æã®ã·ã¼ã±ã³ã¹çªå·ã®åæå¤*/485 init_receive_seq(cep); /* éåä¿¡ã·ã¼ã±ã³ã¹çªå·ãåæåããã*/468 cep->snd_wnd = tcph->win; /* snd_wnd: 相手の受信可能ウィンドサイズ */ 469 cep->irs = tcph->seq; /* irs: 相手のシーケンス番号の初期値 */ 470 init_receive_seq(cep); /* 送受信シーケンス番号を初期化する。 */ 486 471 487 472 if (tcph->flags & TCP_FLG_ACK) { 488 473 /* 489 * ACK ãã©ã°ãããã¨ãã®å¦ç474 * ACK フラグがあるときの処理 490 475 * 491 * åä¿¡ãæå¾ 492 ãã¦ããæ大㮠SEQ (rcv_adv) ã 493 * åä¿¡å¯è½ãªã¦ã£ã³ããµã¤ãº (rcv_wnd) åé²ããã 494 */ 495 cep->rcv_adv += cep->rcv_wnd; /* rcv_adv: åä¿¡ãæå¾ 496 ãã¦ããæ大㮠SEQ */ 497 /* rcv_wnd: åä¿¡å¯è½ãªã¦ã£ã³ããµã¤ãº */ 498 499 /* æªç¢ºèªã®æå°éä¿¡ SEQ (snd_una) ã SYN å (1 ãªã¯ããã) é²ããã*/ 476 * 受信を期待している最大の SEQ (rcv_adv) を 477 * 受信可能なウィンドサイズ (rcv_wnd) 分進める。 478 */ 479 cep->rcv_adv += cep->rcv_wnd; /* rcv_adv: 受信を期待している最大の SEQ */ 480 /* rcv_wnd: 受信可能なウィンドサイズ */ 481 482 /* 未確認の最小送信 SEQ (snd_una) を SYN 分 (1 オクテット) 進める。*/ 500 483 cep->snd_una ++; 501 484 502 485 #ifdef TCP_CFG_DELAY_ACK 503 486 504 if (tcph->sum != 0) /* tcph->sum 㯠SDU é·*/487 if (tcph->sum != 0) /* tcph->sum は SDU 長 */ 505 488 cep->flags |= TCP_CEP_FLG_DEL_ACK; 506 489 else … … 515 498 if (cep->flags & TCP_CEP_FLG_NEED_FIN) { 516 499 /* 517 * CEP 㧠FIN éä¿¡ãè¦æ±ããã¦ããã°ã 518 * åæå¦çãéå§ãã 519 * CEP ã®ç¶æ 520 ã FIN Wait 1 ã«ããã 500 * CEP で FIN 送信が要求されていれば、 501 * 切断処理を開始し、 502 * CEP の状態を FIN Wait 1 にする。 521 503 */ 522 504 cep->fsm_state = TCP_FSM_FIN_WAIT_1; … … 526 508 else { 527 509 /* 528 * ç¸æãã ACK ãå¿çãããã®ã§ã 529 * CEP ã®ç¶æ 530 ã ã³ãã¯ã·ã§ã³éè¨å®äºç¶æ 531 ã«ããã 510 * 相手から ACK が応答されたので、 511 * CEP の状態を コネクション開設完了状態にする。 532 512 */ 533 513 cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_IDLE; … … 540 520 if (cep->snd_nblk_tfn == TFN_TCP_CON_CEP) { 541 521 542 /* ç¸æã®ã¢ãã¬ã¹ãã³ãã¼ããã*/522 /* 相手のアドレスをコピーする。*/ 543 523 *cep->p_dstaddr = cep->dstaddr; 544 524 … … 576 556 } 577 557 else { 578 /* ACK ãã©ã°ããªãã¨ãã¯ãACK ãéã£ã¦ãCEP ã®ç¶æ 579 ã SYN åä¿¡æ¸ã¿ã«ããã*/ 558 /* ACK フラグがないときは、ACK を送って、CEP の状態を SYN 受信済みにする。*/ 580 559 cep->flags |= TCP_CEP_FLG_ACK_NOW; 581 560 cep->timer[TCP_TIM_REXMT] = 0; … … 587 566 588 567 /* 589 * trim_length -- åä¿¡ãã SDU é·ã調æ´ããã568 * trim_length -- 受信した SDU 長を調整する。 590 569 */ 591 570 … … 594 573 { 595 574 tcph->seq ++; 596 if (tcph->sum > cep->rcv_wnd) { /* 注æ: tcph->sum 㯠SDU é·*/597 /* 598 * SDU é·ãåä¿¡ã¦ã£ã³ããµã¤ãºãã大ããã¨ãã¯ãåä¿¡ã¦ã£ã³ããµã¤ãºä»¥éã¯599 * ç ´æ£ããFIN ã«å¿çããªããã¨ã§ãç ´æ£ãããã¼ã¿ãåéãããã575 if (tcph->sum > cep->rcv_wnd) { /* 注意: tcph->sum は SDU 長 */ 576 /* 577 * SDU 長が受信ウィンドサイズより大きいときは、受信ウィンドサイズ以降は 578 * 破棄し、FIN に応答しないことで、破棄したデータを再送させる。 600 579 */ 601 580 tcph->sum = (uint16_t)cep->rcv_wnd; 602 581 tcph->flags &= ~TCP_FLG_FIN; 603 582 } 604 cep->snd_wl1 = tcph->seq - 1; /* cep->snd_wl1: ã¦ã£ã³ãæ´æ° SEQ çªå·*/583 cep->snd_wl1 = tcph->seq - 1; /* cep->snd_wl1: ウィンド更新 SEQ 番号 */ 605 584 606 585 #ifdef TCP_CFG_EXTENTIONS 607 cep->rcv_up = tcph->seq; /* cep->rcv_up : åä¿¡ããç·æ¥ãã¤ã³ã¿*/586 cep->rcv_up = tcph->seq; /* cep->rcv_up : 受信した緊急ポインタ */ 608 587 #endif 609 588 } 610 589 611 590 /* 612 * proc_ack2 -- ACK ã®å¦ç(2)591 * proc_ack2 -- ACK の処理 (2) 613 592 * 614 * æ»ãå¤593 * 戻り値 615 594 * 616 * RET_OK æ£å¸¸617 * RET_RETURN æ£å¸¸ããªã¿ã¼ã³ããã618 * RET_DROP ã¨ã©ã¼ãã»ã°ã¡ã³ããç ´æ£ããã619 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã595 * RET_OK 正常 596 * RET_RETURN 正常、リターンする。 597 * RET_DROP エラー、セグメントを破棄する。 598 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 620 599 */ 621 600 … … 631 610 632 611 /* 633 * ç¸æã«å信確èªããã ACK ãããã¾ã 確èªããã¦ããªã634 * æå°éä¿¡ SEQ (snd_una) ãå¼ãã¨ãéä¿¡ã¦ã£ã³ããããã¡ãã635 * åé¤ãã¦ãããªã¯ãããæ° (acked) ã«ãªãã612 * 相手に受信確認された ACK から、まだ確認されていない 613 * 最小送信 SEQ (snd_una) を引くと、送信ウィンドバッファから 614 * 削除してよいオクテット数 (acked) になる。 636 615 */ 637 616 acked = tcph->ack - cep->snd_una; … … 639 618 640 619 /* 641 * å¾å¾©æéè¨æ¸¬ (rtt) ãè¨å®ããã¦ãã¦ãè¨æ¸¬éå§ SEQ ãã642 * å¾ã® ACK ãåä¿¡ããããã¿ã¤ãããã¯ãªãããã£ã³ã»ã«ãã643 * åéã¿ã¤ããåè¨å®ããã620 * 往復時間計測 (rtt) が設定されていて、計測開始 SEQ より 621 * 後の ACK を受信したら、タイマバックオフをキャンセルし、 622 * 再送タイマを再設定する。 644 623 */ 645 624 if (cep->rtt && SEQ_GT(tcph->ack, cep->rtseq)) { … … 648 627 649 628 /* 650 * å 651 ¨ã¦ã®æªç¢ºèªãã¼ã¿ã ACK ãããããåéã¿ã¤ããåæ¢ãã 652 * åéãè¨æ¶ãã (ããã«åºåãæç¶)ã 653 * ãããACK ãã¹ããããã«å¤ãã®ãã¼ã¿ããããªããåéã¿ã¤ãã« 654 * ç¾å¨ã®åéã¿ã¤ã ã¢ã¦ããè¨å®ããã 655 */ 656 if (tcph->ack == cep->snd_max) { /* cep->snd_max: éä¿¡ããæ大 SEQ */ 629 * 全ての未確認データが ACK されたら、再送タイマを停止し、 630 * 再開を記憶する (さらに出力か持続)。 631 * もし、ACK すべき、さらに多くのデータがあるなら、再送タイマに 632 * 現在の再送タイムアウトを設定する。 633 */ 634 if (tcph->ack == cep->snd_max) { /* cep->snd_max: 送信した最大 SEQ */ 657 635 658 636 #ifdef TCP_CFG_SWBUF_CSAVE 659 637 660 638 /* 661 * éä¿¡ã¦ã£ã³ããããã¡ã®çã³ãã¼æ©è½ãæå¹ã®å ´åã¯ã662 * éä¿¡æ¸ã¿ã§ãACKãå®äºããã¾ã§åéã¿ã¤ããå¤æ´ããªãã639 * 送信ウィンドバッファの省コピー機能が有効の場合は、 640 * 送信済みで、ACKが完了するまで再送タイマを変更しない。 663 641 */ 664 642 if ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_ACKED) … … 674 652 } 675 653 else if (cep->timer[TCP_TIM_PERSIST] == 0) { 676 cep->timer[TCP_TIM_REXMT] = cep->rxtcur; /* cep->rxtcur: ç¾å¨ã®åéã¿ã¤ã ã¢ã¦ã*/677 } 678 679 /* ç¸æãå信確èªãããã¼ã¿ãããã¨ãã®å¦ç*/654 cep->timer[TCP_TIM_REXMT] = cep->rxtcur; /* cep->rxtcur: 現在の再送タイムアウト */ 655 } 656 657 /* 相手が受信確認したデータがあるときの処理 */ 680 658 if (acked) { 681 uint32_t cw = cep->snd_cwnd; /* cep->snd_cwnd: 輻輳ã¦ã£ã³ããµã¤ãº*/682 uint32_t incr = cep->maxseg; /* cep->maxseg: æ大ã»ã°ã¡ã³ããµã¤ãº*/683 684 /* 685 * æ°ãã«ç¸æãå信確èªãããã¼ã¿ããã£ãã¨ãã¯ã686 * 輻輳ã¦ã£ã³ããµã¤ãºã大ããããã687 * 輻輳ã¦ã£ã³ããµã¤ãº (snd_cwnd) ã688 * 輻輳ã¦ã£ã³ããµã¤ãºã®ãããå¤ (snd_ssthresh) ãã大ããã¨ãã¯689 * 輻輳åé¿å¶å¾¡ãè¡ãã659 uint32_t cw = cep->snd_cwnd; /* cep->snd_cwnd: 輻輳ウィンドサイズ */ 660 uint32_t incr = cep->maxseg; /* cep->maxseg: 最大セグメントサイズ */ 661 662 /* 663 * 新たに相手が受信確認したデータがあったときは、 664 * 輻輳ウィンドサイズを大きくする。 665 * 輻輳ウィンドサイズ (snd_cwnd) が 666 * 輻輳ウィンドサイズのしきい値 (snd_ssthresh) より大きいときは 667 * 輻輳回避制御を行い。 690 668 * 691 669 * snd_cwnd = snd_cwnd + maxseg * maxseg / snd_cwnd; 692 670 * 693 * çãããå°ããã¨ãã¯ãã¹ãã¼ã¹ã¿ã¼ãå¶å¾¡ãè¡ãã671 * 等しいか小さいときは、スロースタート制御を行う。 694 672 * 695 673 * snd_cwnd = snd_cwnd + maxseg … … 697 675 */ 698 676 if (cw > cep->snd_ssthresh) 699 /* 輻輳åé¿å¶å¾¡*/677 /* 輻輳回避制御 */ 700 678 incr = incr * incr / cw; 701 679 … … 706 684 707 685 /* 708 * éä¿¡ã¦ã£ã³ããããã¡ãããç¸æãå信確èªãããã¼ã¿æ° (acked) ã®ãã¼ã¿ãåé¤ããã686 * 送信ウィンドバッファから、相手が受信確認したデータ数 (acked) のデータを削除する。 709 687 */ 710 688 if (acked > cep->swbuf_count) { … … 719 697 } 720 698 721 /* éä¿¡ã¦ã£ã³ããããã¡ã«ç©ºããã§ãããã¨ãç¥ãããã*/699 /* 送信ウィンドバッファに空きができたことを知らせる。*/ 722 700 syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY)); 723 701 724 702 /* 725 * éé確èªããã¦ããªãæå°éä¿¡ SEQ (snd_una) ã726 * ä»åéé確èªããã ACK ã¾ã§é²ãã727 * 次ã®éä¿¡ãã¼ã¿ã® SEQ (snd_nxt) ããæ°ãã728 * éé確èªããã¦ããªãæå°éä¿¡SEQ (snd_una)729 * ã¾ã§é²ããã703 * 送達確認されていない最小送信 SEQ (snd_una) を 704 * 今回送達確認された ACK まで進め、 705 * 次の送信データの SEQ (snd_nxt) も、新しい 706 * 送達確認されていない最小送信 SEQ (snd_una) 707 * まで進める。 730 708 */ 731 709 cep->snd_una += acked; … … 734 712 735 713 /* 736 * ç¶æ 737 ã«ããåå² 714 * 状態により分岐 738 715 */ 739 716 switch (cep->fsm_state) { 740 case TCP_FSM_FIN_WAIT_1: /* APP ãçµäºãFIN éä¿¡æ¸ã¿ãACK å¾ 741 ã¡ */ 717 case TCP_FSM_FIN_WAIT_1: /* APP が終了、FIN 送信済み、ACK 待ち */ 742 718 if (ourfinisacked) { 743 719 cep->fsm_state = TCP_FSM_FIN_WAIT_2; … … 745 721 } 746 722 break; 747 case TCP_FSM_CLOSING: /* åæã¯ãã¼ãºãFIN 交ææ¸ã¿ãACK å¾ 748 ã¡ */ 723 case TCP_FSM_CLOSING: /* 同時クローズ、FIN 交換済み、ACK 待ち */ 749 724 if (ourfinisacked) { 750 725 /* 751 * éä¿¡ãã FIN ã確èªããã¦ããã°ç¶æ 752 ãå¤æ´ãã 753 * ãã¹ã¦ã®ã¿ã¤ãããªã»ããããå¾ã2MSL ã¿ã¤ããè¨å®ããã 726 * 送信した FIN が確認されていれば状態を変更し、 727 * すべてのタイマをリセットした後、2MSL タイマを設定する。 754 728 */ 755 729 cep->fsm_state = TCP_FSM_TIME_WAIT; … … 758 732 } 759 733 break; 760 case TCP_FSM_LAST_ACK: /* APP ãçµäºãACK å¾ 761 ã¡ */ 734 case TCP_FSM_LAST_ACK: /* APP が終了、ACK 待ち */ 762 735 if (ourfinisacked) { 763 736 /* 764 * éä¿¡ãã FIN ã確èªããã¦ããã°ãcep ãã¯ãã¼ãºãã765 * ã»ã°ã¡ã³ããç ´æ£ããã737 * 送信した FIN が確認されていれば、cep をクローズし、 738 * セグメントを破棄する。 766 739 */ 767 740 cep = tcp_close(cep); … … 769 742 } 770 743 break; 771 case TCP_FSM_TIME_WAIT: /* ç¸æããã® FIN åä¿¡æ¸ã¿ãæéå¾ 772 ã¡ */ 744 case TCP_FSM_TIME_WAIT: /* 相手からの FIN 受信済み、時間待ち */ 773 745 /* 774 * ç¸æãã FIN ãåéããããããä¸åº¦2MSL ã¿ã¤ããè¨å®ãã775 * ACK éä¿¡å¾ãã»ã°ã¡ã³ããç ´æ£ããã746 * 相手から FIN が再送された。もう一度2MSL タイマを設定し、 747 * ACK 送信後、セグメントを破棄する。 776 748 */ 777 749 cep->timer[TCP_TIM_2MSL] = 2 * TCP_TVAL_MSL; … … 784 756 785 757 /* 786 * proc_ack1 -- ACK ã®å¦ç(1)758 * proc_ack1 -- ACK の処理 (1) 787 759 * 788 * æ»ãå¤:789 * RET_OK æ£å¸¸790 * RET_RETURN æ£å¸¸ããªã¿ã¼ã³ããã791 * RET_DROP ã¨ã©ã¼ãã»ã°ã¡ã³ããç ´æ£ããã792 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã760 * 戻り値: 761 * RET_OK 正常 762 * RET_RETURN 正常、リターンする。 763 * RET_DROP エラー、セグメントを破棄する。 764 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 793 765 * 794 766 */ … … 800 772 801 773 switch (cep->fsm_state) { 802 case TCP_FSM_SYN_RECVD: /* SYN ãåä¿¡ããSYN éä¿¡æ¸ã¿ */ 803 804 /* ç¶æ 805 ãå¤æ´ããã*/ 774 case TCP_FSM_SYN_RECVD: /* SYN を受信し、SYN 送信済み */ 775 776 /* 状態を変更する。*/ 806 777 if (cep->flags & TCP_CEP_FLG_NEED_FIN) { 807 778 cep->fsm_state = TCP_FSM_FIN_WAIT_1; … … 812 783 cep->fsm_state = TCP_FSM_ESTABLISHED; 813 784 814 /* TCP é信端ç¹ããTCP åä»å£ã解æ¾ããã*/785 /* TCP 通信端点からTCP 受付口を解放する。*/ 815 786 cep->rep = NULL; 816 787 … … 825 796 if (cep->rcv_nblk_tfn == TFN_TCP_ACP_CEP) { 826 797 827 /* ç¸æã®ã¢ãã¬ã¹ãã³ãã¼ããã*/798 /* 相手のアドレスをコピーする。*/ 828 799 829 800 #if defined(_IP6_CFG) && defined(_IP4_CFG) … … 875 846 if (cep->snd_nblk_tfn == TFN_TCP_CON_CEP) { 876 847 877 /* ç¸æã®ã¢ãã¬ã¹ãã³ãã¼ããã*/848 /* 相手のアドレスをコピーする。*/ 878 849 *cep->p_dstaddr = cep->dstaddr; 879 850 … … 923 894 924 895 /* 925 * SDU ããªã FIN ãã¤ãã¦ããªããã°ãtcp_move_ra2rw() ãå¼åºãã926 */ 927 if (tcph->sum == 0 && (tcph->flags & TCP_FLG_FIN) == 0) /* tcph->sum 㯠SDU é·*/896 * SDU がなく FIN がついていなければ、tcp_move_ra2rw() を呼出す。 897 */ 898 if (tcph->sum == 0 && (tcph->flags & TCP_FLG_FIN) == 0) /* tcph->sum は SDU 長 */ 928 899 tcph->flags = tcp_move_ra2rw(cep, tcph->flags); 929 900 930 cep->snd_wl1 = tcph->seq - 1; /* snd_wl1: ã¦ã£ã³ãæ´æ°SEQ */931 932 /* break; ä¸ã«è½ã¡ãã*/901 cep->snd_wl1 = tcph->seq - 1; /* snd_wl1: ウィンド更新 SEQ */ 902 903 /* break; 下に落ちる。*/ 933 904 934 case TCP_FSM_ESTABLISHED: /* ã³ãã¯ã·ã§ã³éè¨å®äº */ 935 case TCP_FSM_FIN_WAIT_1: /* çµäºãã¦ãFIN éä¿¡æ¸ã¿ */ 936 case TCP_FSM_FIN_WAIT_2: /* çµäºãFIN ä¼é確èªåä¿¡ãFINå¾ 937 ã¡*/ 938 case TCP_FSM_CLOSE_WAIT: /* FIN åä¿¡ãã¯ãã¼ãºå¾ 939 ã¡ */ 940 case TCP_FSM_CLOSING: /* çµäºãFIN 交ææ¸ã¿ãACK å¾ 941 ã¡ */ 942 case TCP_FSM_LAST_ACK: /* FIN åä¿¡ãçµäºãACK å¾ 943 ã¡ */ 944 case TCP_FSM_TIME_WAIT: /* çµäºãæéå¾ 945 ã¡ */ 905 case TCP_FSM_ESTABLISHED: /* コネクション開設完了 */ 906 case TCP_FSM_FIN_WAIT_1: /* 終了して、FIN 送信済み */ 907 case TCP_FSM_FIN_WAIT_2: /* 終了、FIN 伝達確認受信、FIN待ち*/ 908 case TCP_FSM_CLOSE_WAIT: /* FIN 受信、クローズ待ち */ 909 case TCP_FSM_CLOSING: /* 終了、FIN 交換済み、ACK 待ち */ 910 case TCP_FSM_LAST_ACK: /* FIN 受信、終了、ACK 待ち */ 911 case TCP_FSM_TIME_WAIT: /* 終了、時間待ち */ 946 912 947 913 if (SEQ_LE(tcph->ack, cep->snd_una)) { 948 914 949 915 /* 950 * åä¿¡ç¢ºèª ACK ã æªç¢ºèªã®æå°éä¿¡ SEQ (snd_una) ã¨åãã以åã®ã¨ãã®å¦ç951 * ã¤ã¾ããå¤éã« ACK ãåä¿¡ãããã¨ãæå³ãã¦ããã916 * 受信確認 ACK が 未確認の最小送信 SEQ (snd_una) と同じか以前のときの処理 917 * つまり、多重に ACK を受信したことを意味している。 952 918 */ 953 919 954 if (tcph->sum == 0 && tcph->win == cep->snd_wnd) { /* tcph->sum 㯠SDU é·*/920 if (tcph->sum == 0 && tcph->win == cep->snd_wnd) { /* tcph->sum は SDU 長 */ 955 921 956 922 /* 957 * SDU ããªããç¸æã®ã¦ã£ã³ããµã¤ãºãå¤æ´ããã¦ããªããã°ã958 * ãã§ã«éä¿¡ããã»ã°ã¡ã³ãã®ä¸ã§ãACK (tcph->ack) ã¨959 * åã SEQ ããå§ã¾ãã»ã°ã¡ã³ãããéä¸ã§æ¶å¤±ããå¯è½æ§ãããã960 * ãã®å ´åã¯ãé«éå転éã¨é«éãªã«ããªãè¡ãã923 * SDU がなく、相手のウィンドサイズが変更されていなければ、 924 * すでに送信したセグメントの中で、ACK (tcph->ack) と 925 * 同じ SEQ から始まるセグメントが、途中で消失した可能性がある。 926 * この場合は、高速再転送と高速リカバリを行う。 961 927 */ 962 928 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_DUP_ACKS], 1); … … 965 931 966 932 /* 967 * åéã¿ã¤ããã»ããããã¦ããªãã¨ãã968 * ã¾ãã¯ãACK (tcph->ack) ã¨æªç¢ºèªã®æå°éä¿¡ SEQã969 * ä¸è´ããªãã¨ãã¯ãå¤é ACK æ°ã 0 ã«ããã933 * 再送タイマがセットされていないとき、 934 * または、ACK (tcph->ack) と未確認の最小送信 SEQが 935 * 一致しないときは、多重 ACK 数を 0 にする。 970 936 */ 971 937 cep->dupacks = 0; … … 975 941 976 942 /* 977 * å¤é ACK æ°ããããå¤ (æ¨æº 3) ã«ãªã£ãã978 * é«éå転éå¦çãéå§ããã943 * 多重 ACK 数がしきい値 (標準 3) になったら 944 * 高速再転送処理を開始する。 979 945 */ 980 946 uint_t win; 981 947 982 948 /* 983 * 輻輳ã¦ã£ã³ããµã¤ãº(snd_cwnd)ã®ãããå¤ãè¨å®ããã949 * 輻輳ウィンドサイズ(snd_cwnd)のしきい値を設定する。 984 950 * 985 * ç¸æã®åä¿¡å¯è½ã¦ã£ã³ããµã¤ãº (snd_wnd) ã986 * 輻輳ã¦ã£ã³ããµã¤ãº (snd_cwnd) ã® 1/2ã987 * ãã ãã2 * maxseg 以ä¸ã951 * 相手の受信可能ウィンドサイズ (snd_wnd) か 952 * 輻輳ウィンドサイズ (snd_cwnd) の 1/2。 953 * ただし、2 * maxseg 以上。 988 954 * 989 955 */ … … 996 962 cep->snd_ssthresh = win * cep->maxseg; 997 963 998 /* åéã¿ã¤ãã¨å¾å¾©æéããªã»ããããã*/964 /* 再送タイマと往復時間をリセットする。*/ 999 965 cep->timer[TCP_TIM_REXMT] = 0; 1000 966 cep->rtt = 0; 1001 967 1002 /* æ¶å¤±ããã»ã°ã¡ã³ããéä¿¡ããã*/968 /* 消失したセグメントを送信する。*/ 1003 969 cep->snd_old_nxt = cep->snd_nxt; 1004 970 cep->snd_nxt = tcph->ack; … … 1006 972 1007 973 /* 1008 * snd_nxt ãå 1009 ã«æ»ãããã«è¨å®ã㦠1010 * éä¿¡ãæ示ããã 974 * snd_nxt を元に戻すように設定して 975 * 送信を指示する。 1011 976 */ 1012 977 cep->flags |= TCP_CEP_FLG_POST_OUTPUT | … … 1016 981 sig_sem(SEM_TCP_POST_OUTPUT); 1017 982 1018 /* 輻輳ã¦ã£ã³ããµã¤ãºãæ´æ°ããã*/983 /* 輻輳ウィンドサイズを更新する。*/ 1019 984 cep->snd_cwnd = (uint16_t)(cep->snd_ssthresh 1020 985 + cep->maxseg * cep->dupacks); … … 1026 991 1027 992 /* 1028 * å¤é ACK æ°ããããå¤ (æ¨æº 3) ãè¶ 1029 ããã 1030 * 輻輳ã¦ã£ã³ããµã¤ãºãå¢å ããªããåéããã 993 * 多重 ACK 数がしきい値 (標準 3) を超えたら 994 * 輻輳ウィンドサイズを増加しながら再送する。 1031 995 */ 1032 996 cep->snd_cwnd += cep->maxseg; 1033 997 1034 /* éä¿¡ãæ示ããã*/998 /* 送信を指示する。*/ 1035 999 cep->flags |= TCP_CEP_FLG_POST_OUTPUT; 1036 1000 sig_sem(SEM_TCP_POST_OUTPUT); … … 1045 1009 1046 1010 /* 1047 * åä¿¡ç¢ºèª ACK ã æªç¢ºèªã®æå°éä¿¡ SEQ (snd_una) 以éã®ã¨ãã®å¦ç1011 * 受信確認 ACK が 未確認の最小送信 SEQ (snd_una) 以降のときの処理 1048 1012 */ 1049 1013 if (cep->dupacks >= MAX_TCP_REXMT_THRESH && cep->snd_cwnd > cep->snd_ssthresh) 1050 1014 /* 1051 * é«éå転éãè¡ã£ã¦ããã¨ãã¯ã輻輳ã¦ã£ã³ããµã¤ãºããããå¤ã¾ã§æ»ãã1015 * 高速再転送を行っていたときは、輻輳ウィンドサイズをしきい値まで戻す。 1052 1016 */ 1053 1017 cep->snd_cwnd = (uint16_t)cep->snd_ssthresh; … … 1057 1021 if (SEQ_GT(tcph->ack, cep->snd_max)) 1058 1022 /* 1059 * åä¿¡ãã ACK ãéä¿¡ããæ大 SEQ ãè¶ 1060 ãã¦ããã¨ãã®å¦ç 1023 * 受信した ACK が送信した最大 SEQ を超えていたときの処理 1061 1024 */ 1062 1025 return drop_after_ack(input, cep, thoff); … … 1064 1027 if (cep->flags & TCP_CEP_FLG_NEED_SYN) { 1065 1028 /* 1066 * SYN éä¿¡è¦æ±ãåãæ¶ãã¦ãæªç¢ºèªã®æå°éä¿¡ SEQ ãé²ããã1029 * SYN 送信要求を取り消して、未確認の最小送信 SEQ を進める。 1067 1030 */ 1068 1031 cep->flags &= ~TCP_CEP_FLG_NEED_SYN; … … 1077 1040 1078 1041 /* 1079 * update_wnd -- ã¦ã£ã³ããµã¤ãºãæ´æ°ããã1042 * update_wnd -- ウィンドサイズを更新する。 1080 1043 * 1081 * æ»ãå¤: éä¿¡ãå¿ 1082 è¦ãªã true ãè¿ãã 1044 * 戻り値: 送信が必要なら true を返す。 1083 1045 */ 1084 1046 … … 1088 1050 1089 1051 /* 1090 * æ´æ°æ¡ä»¶1052 * 更新条件 1091 1053 * 1092 * ACK ãã©ã°ãã»ããããã¦ãã&&1093 * ( ååã¦ã£ã³ããæ´æ°ãã SEQ (snd_wl1) ã SEQ ããå||1094 * ååã¦ã£ã³ããæ´æ°ãã SEQ (snd_wl1) ã SEQ ã¨åã&&1095 * ( ååã¦ã£ã³ããæ´æ°ãã ACK (snd_wl2) ã ACK ããå||1096 * ( ååã¦ã£ã³ããæ´æ°ãã ACK (snd_wl2) ã ACK ã¨åã&&1097 * WIN ãç¸æã®åä¿¡å¯è½ã¦ã£ã³ããµã¤ãº (snd_wnd) ãã大ãã1054 * ACK フラグがセットされている && 1055 * (前回ウィンドを更新した SEQ (snd_wl1) が SEQ より前 || 1056 * 前回ウィンドを更新した SEQ (snd_wl1) が SEQ と同じ && 1057 * (前回ウィンドを更新した ACK (snd_wl2) が ACK より前 || 1058 * (前回ウィンドを更新した ACK (snd_wl2) が ACK と同じ && 1059 * WIN が相手の受信可能ウィンドサイズ (snd_wnd) より大きい 1098 1060 * ) 1099 1061 * ) … … 1111 1073 1112 1074 if (cep->snd_wnd > cep->max_sndwnd) 1113 /* ä»ã¾ã§ã®æ大éä¿¡ã¦ã£ã³ããµã¤ãºãæ´æ°ããã*/1075 /* 今までの最大送信ウィンドサイズを更新する。*/ 1114 1076 cep->max_sndwnd = cep->snd_wnd; 1115 1077 … … 1119 1081 1120 1082 /* 1121 * éä¿¡ã¦ã£ã³ããããã¡ç¨ã®ãããã¯ã¼ã¯ãããã¡å²ãå½ã¦ä¸ã§ã 1122 * ç¸æã®åä¿¡ã¦ã£ã³ãã空ãã®ãå¾ 1123 ã£ã¦ããã¨ãã®å¦ç 1083 * 送信ウィンドバッファ用のネットワークバッファ割り当て中で、 1084 * 相手の受信ウィンドが空くのを待っているときの処理 1124 1085 */ 1125 1086 if (cep->snd_wnd > 0) { 1126 1087 1127 1088 /* 1128 * ç¸æã®åä¿¡ã¦ã£ã³ãã空ããã¨ãã¯ã1129 * éä¿¡ã¦ã£ã³ããããã¡ç¨ã®ãããã¯ã¼ã¯ãããã¡å²ãå½ã¦ãåéããã1089 * 相手の受信ウィンドが空いたときは、 1090 * 送信ウィンドバッファ用のネットワークバッファ割り当てを再開する。 1130 1091 */ 1131 1092 cep->flags = (cep->flags & ~TCP_CEP_FLG_WBCS_MASK) … … 1144 1105 1145 1106 /* 1146 * proc_urg -- ç·æ¥ãã¼ã¿ã¤ãã®ã»ã°ã¡ã³ãã®å¦ç1107 * proc_urg -- 緊急データつきのセグメントの処理 1147 1108 */ 1148 1109 … … 1155 1116 TCP_FSM_HAVE_RCVD_FIN(cep->fsm_state) == 0) { 1156 1117 1157 /* ç·æ¥ãã¼ã¿ã¤ãã®ã»ã°ã¡ã³ãã®å¦ç*/1118 /* 緊急データつきのセグメントの処理 */ 1158 1119 1159 1120 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_URG_SEGS], 1); … … 1161 1122 1162 1123 /* 1163 * ç·æ¥ãã¤ã³ã¿ã®ä½ç½®ãåä¿¡ã¦ã£ã³ããããã¡ã® 1164 * ç¯å²ãè¶ 1165 ããã¨ãã¯ä½ãããªãã 1124 * 緊急ポインタの位置が受信ウィンドバッファの 1125 * 範囲を超えるときは何もしない。 1166 1126 */ 1167 1127 tcph->urp = 0; … … 1170 1130 1171 1131 if (SEQ_GT(tcph->seq + tcph->urp, cep->rcv_up)) 1172 /* ç·æ¥ãã¤ã³ã¿ãæ´æ°ãããã¨ãã®å¦ç*/1132 /* 緊急ポインタが更新されたときの処理 */ 1173 1133 cep->rcv_up = tcph->seq + tcph->urp; 1174 1134 1175 if ((tcph->flags & TCP_FLG_URG) && (tcph->urp + TCP_CFG_URG_OFFSET) < tcph->sum) { /* tcph->sum 㯠TCP ã® SDU é·*/1135 if ((tcph->flags & TCP_FLG_URG) && (tcph->urp + TCP_CFG_URG_OFFSET) < tcph->sum) { /* tcph->sum は TCP の SDU 長 */ 1176 1136 1177 1137 /* 1178 * ç·æ¥ãã¤ã³ã¿ã®ä½ç½®ããä»ååä¿¡ããã»ã°ã¡ã³ãå 1179 ã®å ´åã¯ã 1180 * ã³ã¼ã«ããã¯é¢æ°ãå¼ã³åºãã 1138 * 緊急ポインタの位置が、今回受信したセグメント内の場合は、 1139 * コールバック関数を呼び出す。 1181 1140 */ 1182 1141 cep->urg_tcph = tcph; … … 1201 1160 1202 1161 if (cep->urg_tcph != NULL) { 1203 /* ã³ã¼ã«ããã¯é¢æ°å 1204 㧠tcp_rcv_oob() ãå¼åºããªãã£ãã*/ 1162 /* コールバック関数内で tcp_rcv_oob() を呼出さなかった。*/ 1205 1163 cep->urg_tcph = NULL; 1206 1164 tcph->urp = 0; … … 1208 1166 else { 1209 1167 /* 1210 * ã³ã¼ã«ããã¯é¢æ°å 1211 㧠tcp_rcv_oob() ãå¼åºããæã¯ã 1212 * SDU é·ã®è£æ£å¤ãè¨å®ããã 1168 * コールバック関数内で tcp_rcv_oob() を呼出した時は、 1169 * SDU 長の補正値を設定する。 1213 1170 */ 1214 1171 tcph->urp = 1; … … 1237 1194 1238 1195 /* 1239 * drop_after_ack -- åä¿¡ã»ã°ã¡ã³ããç ´æ£ããå¾ãACK ãè¿ã (注æ: ååã¨ã¯åã£ã¦ããªã)ã1196 * drop_after_ack -- 受信セグメントを破棄した後、ACK を返す (注意: 名前とは合っていない)。 1240 1197 * 1241 * æ»ãå¤:1242 * RET_RETURN æ£å¸¸ããªã¿ã¼ã³ããã1243 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã1198 * 戻り値: 1199 * RET_RETURN 正常、リターンする。 1200 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 1244 1201 */ 1245 1202 … … 1250 1207 1251 1208 /* 1252 * SYN åä¿¡ç¶æ 1253 ã§ãACK ãéé確èªããã¦ããªãæå°éä¿¡ SEQ (snd_una) ãã 1254 * åã®å¤ããéä¿¡ãããæ大 SEQ (snd_max) ããå¾ã®å¤ã®å ´åã¯ãç¸æã« RST ã 1255 * éã£ã¦çµäºãããããã¯ã"LAND" DoS æ»æã¸ã®é²å¾¡ã§ãããå½é ããã SYN 1256 * ã»ã°ã¡ã³ããéä¿¡ãã¤ã¥ãããã¼ãéã§ã® ACK ã¹ãã¼ã ãé²ãã 1209 * SYN 受信状態で、ACK が送達確認されていない最小送信 SEQ (snd_una) より 1210 * 前の値か、送信された最大 SEQ (snd_max) より後の値の場合は、相手に RST を 1211 * 送って終了する。これは、"LAND" DoS 攻撃への防御であり、偽造された SYN 1212 * セグメントを送信しつづけるポート間での ACK ストームを防ぐ。 1257 1213 */ 1258 1214 if (cep->fsm_state == TCP_FSM_SYN_RECVD && (tcph->flags & TCP_FLG_ACK) && … … 1263 1219 syscall(rel_net_buf(input)); 1264 1220 1265 /* éä¿¡ãæ示ããã*/1221 /* 送信を指示する。*/ 1266 1222 cep->flags |= TCP_CEP_FLG_ACK_NOW | TCP_CEP_FLG_POST_OUTPUT; 1267 1223 sig_sem(SEM_TCP_POST_OUTPUT); … … 1270 1226 1271 1227 /* 1272 * close_connection -- ã³ãã¯ã·ã§ã³éæ¾å¦çãç¸æãã FIN ãåä¿¡ããã1228 * close_connection -- コネクション開放処理、相手から FIN を受信した。 1273 1229 */ 1274 1230 … … 1295 1251 1296 1252 switch (cep->fsm_state) { 1297 case TCP_FSM_SYN_RECVD: /* SYN ãåä¿¡ããSYN éä¿¡æ¸ã¿*/1298 case TCP_FSM_ESTABLISHED: /* ã³ãã¯ã·ã§ã³éè¨å®äº*/1253 case TCP_FSM_SYN_RECVD: /* SYN を受信し、SYN 送信済み */ 1254 case TCP_FSM_ESTABLISHED: /* コネクション開設完了 */ 1299 1255 cep->fsm_state = TCP_FSM_CLOSE_WAIT; 1300 1256 syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_RWBUF_READY)); 1301 1257 break; 1302 1258 1303 case TCP_FSM_FIN_WAIT_1: /* APP ãçµäºãFIN éä¿¡æ¸ã¿ãACK å¾ 1304 ã¡ */ 1259 case TCP_FSM_FIN_WAIT_1: /* APP が終了、FIN 送信済み、ACK 待ち */ 1305 1260 cep->fsm_state = TCP_FSM_CLOSING; 1306 1261 break; 1307 1262 1308 case TCP_FSM_FIN_WAIT_2: /* ç¸æããã® FIN å¾ 1309 ã¡ */ 1263 case TCP_FSM_FIN_WAIT_2: /* 相手からの FIN 待ち */ 1310 1264 cep->fsm_state = TCP_FSM_TIME_WAIT; 1311 1265 tcp_cancel_timers(cep); … … 1313 1267 1314 1268 /* 1315 * FIN WAIT 2 ç¶æ 1316 ã§ã¯ã 1317 * åä¿¡ã¯å¯è½ã§ãããããã§ã«éä¿¡ã¯çµäºãã¦ããã 1318 * ç¸æã®éä¿¡ãçµäºããã®ã§ãå 1319 ¥åã¿ã¹ã¯ã®ã¿èµ·åºããã 1269 * FIN WAIT 2 状態では、 1270 * 受信は可能であるが、すでに送信は終了している。 1271 * 相手の送信も終了したので、入力タスクのみ起床する。 1320 1272 */ 1321 1273 syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY)); … … 1323 1275 #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 1324 1276 1325 /* ç¸æããã® FIN ã«å¯¾ãã¦å¿çãè¿ãã*/1277 /* 相手からの FIN に対して応答を返す。*/ 1326 1278 tcp_respond(NULL, cep, cep->rcv_nxt, cep->snd_una, 1327 1279 cep->rbufsz - cep->rwbuf_count, TCP_FLG_ACK); … … 1330 1282 1331 1283 /* 1332 * å¿ 1333 è¦ãªæ 1334 å ±ã Time Wait ç¨ TCP é信端ç¹ã«ç§»ãã¦ã 1335 * æ¨æºã® TCP é信端ç¹ãéæ¾ããã 1284 * 必要な情報を Time Wait 用 TCP 通信端点に移して、 1285 * 標準の TCP 通信端点を開放する。 1336 1286 */ 1337 1287 tcp_move_twcep(cep); … … 1341 1291 break; 1342 1292 1343 case TCP_FSM_TIME_WAIT: /* ç¸æããã® FIN åä¿¡æ¸ã¿ãæéå¾ 1344 ã¡ */ 1293 case TCP_FSM_TIME_WAIT: /* 相手からの FIN 受信済み、時間待ち */ 1345 1294 cep->timer[TCP_TIM_2MSL] = 2 * TCP_TVAL_MSL; 1346 1295 break; … … 1349 1298 1350 1299 /* 1351 * tcp_input -- TCP ã®å 1352 ¥åé¢æ° 1300 * tcp_input -- TCP の入力関数 1353 1301 * 1354 * 注æ: input ã«ã¯ IF ããã㨠IP ããããå 1355 é ã«ããã 1302 * 注意: input には IF ヘッダと IP ヘッダが先頭にある。 1356 1303 */ 1357 1304 … … 1379 1326 NET_COUNT_MIB(tcp_stats.tcpInSegs, 1); 1380 1327 1381 /* ãããé·ããã§ãã¯ããã*/1328 /* ヘッダ長をチェックする。*/ 1382 1329 if (input->len < IF_IP_TCP_HDR_SIZE(input)) { 1383 1330 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_BAD_HEADERS], 1); … … 1387 1334 tcph = GET_TCP_HDR(input, *offp); 1388 1335 1389 seglen = input->len - *offp; /* TCP ã®ã»ã°ã¡ã³ãé·*/1336 seglen = input->len - *offp; /* TCP のセグメント長 */ 1390 1337 1391 1338 if (IN_CKSUM(input, IPPROTO_TCP, *offp, (uint_t)seglen) != 0) { … … 1394 1341 } 1395 1342 1396 /* TCP ãããé·ããã§ãã¯ããã*/1343 /* TCP ヘッダ長をチェックする。*/ 1397 1344 if (TCP_HDR_LEN(tcph->doff) < TCP_HDR_SIZE || TCP_HDR_LEN(tcph->doff) > seglen) { 1398 1345 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_BAD_HEADERS], 1); 1399 1346 goto drop; 1400 1347 } 1401 tcph->sum = seglen - TCP_HDR_LEN(tcph->doff); /* ãããã tcph->sum 㯠TCP ã® SDU é·*/1348 tcph->sum = seglen - TCP_HDR_LEN(tcph->doff); /* ここから tcph->sum は TCP の SDU 長 */ 1402 1349 1403 1350 /* 1404 * SYN 㨠FIN ã®ä¸¡ããããã»ããããã¦ããã°ç ´æ£ãããnmap çã®å¯¾ç1405 * ãã ããRFC1644 T/TCP æ¡å¼µæ©è½ã¨ç«¶åããã1351 * SYN と FIN の両ビットがセットされていれば破棄する。nmap 等の対策 1352 * ただし、RFC1644 T/TCP 拡張機能と競合する。 1406 1353 */ 1407 1354 if ((tcph->flags & (TCP_FLG_SYN | TCP_FLG_FIN)) == (TCP_FLG_SYN | TCP_FLG_FIN)) 1408 1355 goto drop; 1409 1356 1410 /* ãããã¯ã¼ã¯ãªã¼ãã¼ãããã¹ããªã¼ãã¼ã«å¤æããã*/1357 /* ネットワークオーダーからホストオーダーに変換する。*/ 1411 1358 1412 1359 NTOHL(tcph->seq); … … 1422 1369 1423 1370 /* 1424 * ç¶æ 1425 ã Time Wait ä¸ã® CEP ãæ¢ç´¢ããã 1371 * 状態が Time Wait 中の CEP を探索する。 1426 1372 */ 1427 1373 twcep = tcp_find_twcep(input, *offp); 1428 1374 if (twcep != NULL) { 1429 1375 1430 if (tcph->flags & TCP_FLG_RST) /* RST ãã©ã°ãåä¿¡ããã¨ãã¯ç¡è¦ããã*/1376 if (tcph->flags & TCP_FLG_RST) /* RST フラグを受信したときは無視する。*/ 1431 1377 goto drop; 1432 1378 else { 1433 1379 1434 1380 /* 1435 * TCP é信端ç¹ã Time Wait ã®æãç¸æãã¹ãããã»ã°ã¡ã³ããæ¥ãã¨ãã¯ã1436 * ç¸æãã¹ãã® FIN ã«å¯¾ããèªãã¹ãã® ACK ã»ã°ã¡ã³ããéä¸ã§1437 * æ失ãããã¨ãæå³ãã¦ããã®ã§ãACK ã»ã°ã¡ã³ããåéããã1381 * TCP 通信端点が Time Wait の時、相手ホストからセグメントが来たときは、 1382 * 相手ホストの FIN に対する自ホストの ACK セグメントが途中で 1383 * 損失したことを意味しているので、ACK セグメントを再送する。 1438 1384 */ 1439 1385 1440 /* ãã¹ããªã¼ãã¼ãããããã¯ã¼ã¯ãªã¼ãã¼ã«æ»ãã*/1386 /* ホストオーダーからネットワークオーダーに戻す。*/ 1441 1387 HTONS(tcph->sport); 1442 1388 HTONS(tcph->dport); … … 1447 1393 } 1448 1394 else 1449 /* æ¨æºã® TCP é信端ç¹ãå¾ãã*/1395 /* 標準の TCP 通信端点を得る。*/ 1450 1396 cep = tcp_find_cep(input, *offp); 1451 1397 1452 1398 #else /* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */ 1453 1399 1454 /* TCP é信端ç¹ãå¾ãã*/1400 /* TCP 通信端点を得る。*/ 1455 1401 cep = tcp_find_cep(input, *offp); 1456 1402 … … 1458 1404 1459 1405 /* 1460 * TCP é信端ç¹ããªãå ´å㨠CEP ã®ç¶æ 1461 ãã¯ãã¼ãºãªãç ´æ£ããã 1406 * TCP 通信端点がない場合と CEP の状態がクローズなら破棄する。 1462 1407 */ 1463 1408 if (cep == NULL) { … … 1477 1422 1478 1423 /* 1479 * ã³ãã¯ã·ã§ã³éè¨æ¸ã¿ã§ã»ã°ã¡ã³ããåä¿¡ããã¨ãã¯ã1480 * ã¢ã¤ãã«æéã¨çå確èªã¿ã¤ãããªã»ããããã1424 * コネクション開設済みでセグメントを受信したときは、 1425 * アイドル時間と生存確認タイマをリセットする。 1481 1426 */ 1482 1427 cep->idle = 0; … … 1485 1430 } 1486 1431 1487 /* CEP ã®ç¶æ 1488 ã LISTEN 以å¤ã®æã¯ããªãã·ã§ã³ãå¦çããã*/ 1432 /* CEP の状態が LISTEN 以外の時は、オプションを処理する。*/ 1489 1433 if (cep->fsm_state != TCP_FSM_LISTEN) 1490 1434 parse_option(tcph, cep); 1491 1435 1492 1436 /* 1493 * åä¿¡å¯è½ã¦ã£ã³ããµã¤ãºãè¨ç®ããã1437 * 受信可能ウィンドサイズを計算する。 1494 1438 * 1495 * rcv_nxt: åä¿¡ãæå¾ 1496 ãã¦ããæå°ã® SEQï¼ãã以åã¯åä¿¡æ¸ã¿ï¼ 1497 * rcv_adv: åä¿¡ãæå¾ 1498 ãã¦ããæ大㮠SEQ 1499 * rbufsz: åä¿¡ã¦ã£ã³ããããã¡ãµã¤ãº 1500 * rwbuf_count: åä¿¡ã¦ã£ã³ããããã¡ã«ãããã¼ã¿é 1501 * tcph->sum: ä»ååä¿¡ãã SDU ãµã¤ãº 1439 * rcv_nxt: 受信を期待している最小の SEQ(これ以前は受信済み) 1440 * rcv_adv: 受信を期待している最大の SEQ 1441 * rbufsz: 受信ウィンドバッファサイズ 1442 * rwbuf_count: 受信ウィンドバッファにあるデータ量 1443 * tcph->sum: 今回受信した SDU サイズ 1502 1444 * 1503 * ä»ååä¿¡ããã»ã°ã¡ã³ããé åºæ´åãã¥ã¼ã«é£çµãã 1504 * å¯è½æ§ãããã®ã§ tcph->sum ãèæ 1505 ®ããã 1445 * 今回受信したセグメントを順序整列キューに連結する 1446 * 可能性があるので tcph->sum を考慮する。 1506 1447 * 1507 1448 */ … … 1514 1455 cep->rcv_wnd = cep->rcv_adv - cep->rcv_nxt; 1515 1456 1516 /* CEP ã®ç¶æ 1517 ã«ããå¦çãè¡ãã*/ 1518 1519 if (cep->fsm_state == TCP_FSM_LISTEN) { /* ååãªã¼ãã³ (LISTEN) ã®å¦çã*/ 1457 /* CEP の状態により処理を行う。*/ 1458 1459 if (cep->fsm_state == TCP_FSM_LISTEN) { /* 受動オープン (LISTEN) の処理。*/ 1520 1460 if ((ret = listening(input, cep, *offp, iss)) == RET_RST_DROP) 1521 1461 goto reset_drop; 1522 1462 else if (ret == RET_DROP) 1523 1463 goto drop; 1524 trim_length(tcph, cep); /* åä¿¡ãã SDU é·ã調æ´ããã*/1525 1526 if (tcph->flags & TCP_FLG_ACK) { /* ACK ãã©ã°ã®å¦ç*/1464 trim_length(tcph, cep); /* 受信した SDU 長を調整する。*/ 1465 1466 if (tcph->flags & TCP_FLG_ACK) { /* ACK フラグの処理 */ 1527 1467 if ((ret = proc_ack2(input, cep, *offp, &needoutput)) == RET_DROP) 1528 1468 goto drop; … … 1533 1473 } 1534 1474 } 1535 else if (cep->fsm_state == TCP_FSM_SYN_SENT) { /* è½åãªã¼ãã³ãSYN éä¿¡æ¸ã¿*/1475 else if (cep->fsm_state == TCP_FSM_SYN_SENT) { /* 能動オープン、SYN 送信済み */ 1536 1476 if ((ret = syn_sent(tcph, cep)) == RET_RST_DROP) 1537 1477 goto reset_drop; 1538 1478 else if (ret == RET_DROP) 1539 1479 goto drop; 1540 trim_length(tcph, cep); /* åä¿¡ãã SDU é·ã調æ´ããã*/1541 1542 if (tcph->flags & TCP_FLG_ACK) { /* ACK ãã©ã°ã®å¦ç*/1480 trim_length(tcph, cep); /* 受信した SDU 長を調整する。*/ 1481 1482 if (tcph->flags & TCP_FLG_ACK) { /* ACK フラグの処理 */ 1543 1483 if ((ret = proc_ack2(input, cep, *offp, &needoutput)) == RET_DROP) 1544 1484 goto drop; … … 1550 1490 } 1551 1491 else { 1552 if (cep->fsm_state == TCP_FSM_SYN_RECVD) { /* SYN ãåä¿¡ãSYN éä¿¡æ¸ã¿*/1492 if (cep->fsm_state == TCP_FSM_SYN_RECVD) { /* SYN を受信、SYN 送信済み */ 1553 1493 /* 1554 * ç¸æããå信確èªãéããã¦æ¥ã¦ãã1494 * 相手から受信確認が送られて来ても、 1555 1495 * 1556 * ACK <= æªç¢ºèªã®æå°éä¿¡SEQ (snd_una) &&1557 * éä¿¡ããæ大SEQ (snd_max) < ACK1496 * ACK <= 未確認の最小送信 SEQ (snd_una) && 1497 * 送信した最大 SEQ (snd_max) < ACK 1558 1498 * 1559 * ãªãããªã»ãããéã£ã¦ã»ã°ã¡ã³ããç ´æ£ããã1499 * なら、リセットを送ってセグメントを破棄する。 1560 1500 */ 1561 1501 if ((tcph->flags & TCP_FLG_ACK) && … … 1566 1506 1567 1507 /* 1568 * RST ãã©ã°ãåä¿¡ããã¨ãã®å¦ç (ç°å¸¸åæ)1508 * RST フラグを受信したときの処理 (異常切断) 1569 1509 */ 1570 1510 if (tcph->flags & TCP_FLG_RST) { … … 1572 1512 SEQ_LT(tcph->seq, cep->last_ack_sent + cep->rcv_wnd)) { 1573 1513 /* 1574 * åä¿¡ããã»ã°ã¡ã³ãã® SEQ ããæå¾ã«éä¿¡ããACK (last_ack_sent)1575 * ãããåä¿¡ã¦ã¤ã³ãã¦ãµã¤ãºã¾ã§ã®éã®å¦ç1514 * 受信したセグメントの SEQ が、最後に送信した ACK (last_ack_sent) 1515 * から、受信ウインドウサイズまでの間の処理 1576 1516 */ 1577 1517 switch (cep->fsm_state) { 1578 case TCP_FSM_SYN_RECVD: /* SYN ãåä¿¡ããSYN éä¿¡æ¸ã¿*/1579 1580 cep->net_error = EV_CNNRF; /* æ¥ç¶ä¸è½*/1518 case TCP_FSM_SYN_RECVD: /* SYN を受信し、SYN 送信済み */ 1519 1520 cep->net_error = EV_CNNRF; /* 接続不能 */ 1581 1521 cep->error = E_CLS; 1582 1522 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_RSTS], 1); … … 1585 1525 break; 1586 1526 1587 case TCP_FSM_ESTABLISHED: /* ã³ãã¯ã·ã§ã³éè¨å®äº */ 1588 case TCP_FSM_CLOSE_WAIT: /* FIN åä¿¡ãã¯ãã¼ãºå¾ 1589 ã¡ */ 1527 case TCP_FSM_ESTABLISHED: /* コネクション開設完了 */ 1528 case TCP_FSM_CLOSE_WAIT: /* FIN 受信、クローズ待ち */ 1590 1529 NET_COUNT_MIB(tcp_stats.tcpEstabResets, 1); 1591 1530 /* fallthrough */ 1592 1531 1593 case TCP_FSM_FIN_WAIT_1: /* çµäºãã¦ãFIN éä¿¡æ¸ã¿ */ 1594 case TCP_FSM_FIN_WAIT_2: /* çµäºãFIN ä¼é確èªåä¿¡ãFINå¾ 1595 ã¡ */ 1596 1597 cep->net_error = EV_CNRST; /* æ¥ç¶ãªã»ãã */ 1532 case TCP_FSM_FIN_WAIT_1: /* 終了して、FIN 送信済み */ 1533 case TCP_FSM_FIN_WAIT_2: /* 終了、FIN 伝達確認受信、FIN待ち */ 1534 1535 cep->net_error = EV_CNRST; /* 接続リセット */ 1598 1536 cep->error = E_CLS; 1599 1537 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_RSTS], 1); 1600 1538 /* no break; */ 1601 1539 1602 case TCP_FSM_CLOSING: /* çµäºãFIN 交ææ¸ã¿ãACK å¾ 1603 ã¡ */ 1604 case TCP_FSM_LAST_ACK: /* FIN åä¿¡ãçµäºãACK å¾ 1605 ã¡ */ 1540 case TCP_FSM_CLOSING: /* 終了、FIN 交換済み、ACK 待ち */ 1541 case TCP_FSM_LAST_ACK: /* FIN 受信、終了、ACK 待ち */ 1606 1542 1607 1543 cep = tcp_close(cep); … … 1613 1549 1614 1550 /* 1615 * CEP ã®ç¶æ 1616 ã SYN ãåä¿¡ããSYN éä¿¡æ¸ã¿ã®å ´åã¯ã 1617 * åä¿¡ã¦ã£ã³ãã«åã¾ãããã«ãã¼ã¿ã 1618 * 調æ´ããåã«ããã®æ¥ç¶ã«ãããã±ãããã©ãããæ¤è¨¼ããã 1551 * CEP の状態が SYN を受信し、SYN 送信済みの場合は、 1552 * 受信ウィンドに収まるようにデータを 1553 * 調整する前に、この接続によるパケットかどうかを検証する。 1619 1554 * 1620 * åä¿¡ããç¸æã® SEQ < ç¸æã® SEQ ã®åæå¤(irs)1555 * 受信した相手の SEQ < 相手の SEQ の初期値 (irs) 1621 1556 * 1622 * ããã¯ã"LAND" DoS æ»æã®é²å¾¡ã§ããã1557 * これは、"LAND" DoS 攻撃の防御である。 1623 1558 */ 1624 1559 if (cep->fsm_state == TCP_FSM_SYN_RECVD && SEQ_LT(tcph->seq, cep->irs)) { … … 1627 1562 1628 1563 /* 1629 * åä¿¡ãæå¾ 1630 ãã¦ããæå°ã® SEQ (rcv_nxt) - åä¿¡ããç¸æã® SEQ ã 1631 * æ£ãªããrcv_nxt 以åã®ãã¼ã¿ã¯ãã§ã«åä¿¡ãã¦ããã®ã§ããã®é¨åã 1632 * åé¤ããã 1564 * 受信を期待している最小の SEQ (rcv_nxt) - 受信した相手の SEQ が 1565 * 正なら、rcv_nxt 以前のデータはすでに受信しているので、その部分を 1566 * 削除する。 1633 1567 * <---------- rcv_wnd ---------> 1634 1568 * rcv_nxt rcv_nxt + rcv_wnd … … 1642 1576 * ^ ^ 1643 1577 * seq seq + len 1644 * <---------------> åé¤ããã1578 * <---------------> 削除する。 1645 1579 */ 1646 1580 todrop = cep->rcv_nxt - tcph->seq; … … 1648 1582 1649 1583 /* 1650 * SYN ãã©ã°ãã¤ãã¦ããã¨ãã¯ããã®å (1 ãªã¯ããã)1651 * SEQ ãé²ããç·æ¥ãã¤ã³ã¿ã¨åé¤ããé·ãã調æ´ããã1584 * SYN フラグがついているときは、その分 (1 オクテット) 1585 * SEQ を進め、緊急ポインタと削除する長さを調整する。 1652 1586 */ 1653 1587 if (tcph->flags & TCP_FLG_SYN) { … … 1662 1596 1663 1597 /* 1664 * åé¤ããé·ãã SDU ããé·ããã¤ã¾ããåä¿¡ãæå¾ 1665 ãã¦ãã 1666 * æå°ã® SEQ (rcv_nxt) ã«éãã¦ããªããã 1667 * åé¤ããé·ãã SDU ã¨åãã§ãFIN ãã©ã°ãã¤ãã¦ãªããã° 1668 * å 1669 ¨ã¦åé¤ããã 1598 * 削除する長さが SDU より長い、つまり、受信を期待している 1599 * 最小の SEQ (rcv_nxt) に達していないか、 1600 * 削除する長さが SDU と同じで、FIN フラグがついてなければ 1601 * 全て削除する。 1670 1602 */ 1671 if ( todrop > tcph->sum || /* tcph->sum 㯠TCP ã® SDU é·*/1603 if ( todrop > tcph->sum || /* tcph->sum は TCP の SDU 長 */ 1672 1604 (todrop == tcph->sum && (tcph->flags & TCP_FLG_FIN) == 0)) { 1673 1605 tcph->flags &= ~TCP_FLG_FIN; 1674 1606 cep->flags |= TCP_CEP_FLG_ACK_NOW; 1675 todrop = tcph->sum; /* tcph->sum 㯠TCP ã® SDU é·*/1607 todrop = tcph->sum; /* tcph->sum は TCP の SDU 長 */ 1676 1608 } 1677 1609 1678 1610 /* 1679 * SDU ãåã«è©°ããã1611 * SDU を前に詰める。 1680 1612 */ 1681 if (todrop < tcph->sum) { /* tcph->sum 㯠TCP ã® SDU é·*/1613 if (todrop < tcph->sum) { /* tcph->sum は TCP の SDU 長 */ 1682 1614 memcpy(GET_TCP_SDU(input, *offp), 1683 1615 GET_TCP_SDU(input, *offp) + todrop, (size_t)(tcph->sum - todrop)); … … 1685 1617 1686 1618 /* 1687 * SEQ 㨠SDU é·ã調æ´ããã1619 * SEQ と SDU 長を調整する。 1688 1620 */ 1689 1621 tcph->seq += todrop; 1690 tcph->sum -= (uint16_t)todrop; /* tcph->sum 㯠TCP ã® SDU é·*/1622 tcph->sum -= (uint16_t)todrop; /* tcph->sum は TCP の SDU 長 */ 1691 1623 1692 1624 /* 1693 * ç·æ¥ãã¤ã³ã¿ã調æ´ããã1625 * 緊急ポインタを調整する。 1694 1626 */ 1695 1627 if (tcph->urp > todrop) … … 1704 1636 1705 1637 /* 1706 * ããã¦ã¼ã¶ã¿ã¹ã¯ãçµäºããå¾ã«ããã¼ã¿ãåä¿¡ãã1707 * å ´åã¯ãRST ãéãã1708 */ 1709 if (cep->fsm_state == TCP_FSM_LAST_ACK && tcph->sum > 0) { /* tcph->sum 㯠TCP ã® SDU é·*/1638 * もしユーザタスクが終了した後に、データを受信した 1639 * 場合は、RST を送る。 1640 */ 1641 if (cep->fsm_state == TCP_FSM_LAST_ACK && tcph->sum > 0) { /* tcph->sum は TCP の SDU 長 */ 1710 1642 cep = tcp_close(cep); 1711 1643 goto reset_drop; … … 1713 1645 1714 1646 /* 1715 * åä¿¡ã»ã°ã¡ã³ããåä¿¡ã¦ã£ã³ããè¶ 1716 ããå ´åã¯ã 1717 * è¶ 1718 ããåãåãã 1647 * 受信セグメントが受信ウィンドを超える場合は、 1648 * 超えた分を削る。 1719 1649 * 1720 1650 * <---------- rcv_wnd ---------> … … 1729 1659 * ^ ^ 1730 1660 * seq seq + len 1731 * <-----> åé¤ããã1732 */ 1733 todrop = (tcph->seq + tcph->sum) - (cep->rcv_nxt + cep->rcv_wnd); /* tcph->sum 㯠TCP ã® SDU é·*/1661 * <-----> 削除する。 1662 */ 1663 todrop = (tcph->seq + tcph->sum) - (cep->rcv_nxt + cep->rcv_wnd); /* tcph->sum は TCP の SDU 長 */ 1734 1664 if (todrop > 0) { 1735 if (todrop > tcph->sum) { /* tcph->sum 㯠TCP ã® SDU é·*/1665 if (todrop > tcph->sum) { /* tcph->sum は TCP の SDU 長 */ 1736 1666 /* 1737 * åä¿¡ãã SDU ã®å 1738 ¨ã¦ãåä¿¡ã¦ã£ã³ããè¶ 1739 ããå ´åã 1667 * 受信した SDU の全てが受信ウィンドを超える場合。 1740 1668 * 1741 * TIME_WAIT ä¸ã«ãæ°ããªæ¥ç¶è¦æ±ãåä¿¡ããã1742 * å¤ãæ¥ç¶ãç ´æ£ããæ°ããªæ¥ç¶ãéå§ããã1743 * ãã ããSEQ ã¯åããé²ãã§ããªããã°ãªããªãã1669 * TIME_WAIT 中に、新たな接続要求を受信したら 1670 * 古い接続を破棄し、新たな接続を開始する。 1671 * ただし、SEQ は前より進んでいなければならない。 1744 1672 */ 1745 1673 if ((tcph->flags & TCP_FLG_SYN) && … … 1753 1681 1754 1682 /* 1755 * åä¿¡ã¦ã£ã³ãã 0 ã§ãåä¿¡ãã SEQ 㨠1756 * åä¿¡ãæå¾ 1757 ãã¦ããæå°ã® SEQ ãä¸è´ããã¨ã㯠1758 * ACK ãè¿ãããã以å¤ã¯ãã¼ã¿ãç ´æ£ããACK ãè¿ãã 1683 * 受信ウィンドが 0 で、受信した SEQ と 1684 * 受信を期待している最小の SEQ が一致したときは 1685 * ACK を返す。それ以外はデータを破棄し、ACK を返す。 1759 1686 */ 1760 1687 if (cep->rcv_wnd == 0 && (tcph->seq == cep->rcv_nxt || tcph->sum == 0)) { … … 1767 1694 } 1768 1695 } 1769 tcph->sum -= (uint16_t)todrop; /* tcph->sum 㯠TCP ã® SDU é·*/1696 tcph->sum -= (uint16_t)todrop; /* tcph->sum は TCP の SDU 長 */ 1770 1697 tcph->flags &= ~(TCP_FLG_PUSH | TCP_FLG_FIN); 1771 1698 } 1772 1699 1773 1700 /* 1774 * ãããSYN ãã»ããããã¦ããã°ã1775 * ã¨ã©ã¼ãªã®ã§ RST ãéããæ¥ç¶ãç ´æ£ããã1701 * もし、SYN がセットされていれば、 1702 * エラーなので RST を送り、接続を破棄する。 1776 1703 */ 1777 1704 if (tcph->flags & TCP_FLG_SYN) { … … 1782 1709 1783 1710 /* 1784 * ãããACK ãã»ããããã¦ããªãå ´åã¯ã 1785 * ç¶æ 1786 ã SYN åä¿¡æ¸ã¿ã 1787 * SYN ãéä¿¡ãããã¨ãã¦ããã°ãå¦çãç¶ãããã 1788 * ãã以å¤ã¯ã»ã°ã¡ã³ããç ´æ£ãã¦çµäºããã 1711 * もし、ACK がセットされていない場合は、 1712 * 状態が SYN 受信済みか 1713 * SYN を送信しようとしていれば、処理を続けるが、 1714 * それ以外はセグメントを破棄して終了する。 1789 1715 */ 1790 1716 if ((tcph->flags & TCP_FLG_ACK) == 0) { … … 1794 1720 else { 1795 1721 /* 1796 * ACK ã®å¦ç1722 * ACK の処理 1797 1723 */ 1798 1724 ret = proc_ack1(input, cep, *offp, &needoutput); … … 1808 1734 /* step 6 */ 1809 1735 1810 /* éä¿¡ã¦ã£ã³ããæ´æ°ããã*/1736 /* 送信ウィンドを更新する。*/ 1811 1737 if (update_wnd(tcph, cep) == true) 1812 1738 needoutput = true; 1813 1739 1814 /* ç·æ¥ãã¼ã¿ãå¦çããã*/1740 /* 緊急データを処理する。*/ 1815 1741 proc_urg(tcph, cep); 1816 1742 … … 1818 1744 1819 1745 /* 1820 * SDU ãããããFIN ãæªåä¿¡ã®ç¶æ 1821 ã§ãæåã« FIN ãåä¿¡ããã¨ãã 1822 * åä¿¡ã»ã°ã¡ã³ããã¥ã¼ã« net_buf ã追å ããã 1823 * ãã以å¤ã®å ´åã¯ãã»ã°ã¡ã³ããç ´æ£ããã 1746 * SDU があるか、FIN を未受信の状態で、最初に FIN を受信したとき、 1747 * 受信セグメントキューに net_buf を追加する。 1748 * それ以外の場合は、セグメントを破棄する。 1824 1749 */ 1825 1750 flags = tcph->flags; 1826 if ((tcph->sum > 0 || (flags & TCP_FLG_FIN)) && /* tcph->sum 㯠TCP ã® SDU é·*/1751 if ((tcph->sum > 0 || (flags & TCP_FLG_FIN)) && /* tcph->sum は TCP の SDU 長 */ 1827 1752 TCP_FSM_HAVE_RCVD_FIN(cep->fsm_state) == 0) { 1828 1753 flags = reassemble(input, cep, *offp, flags); … … 1834 1759 1835 1760 /* 1836 * FIN ãåä¿¡ãããã³ãã¯ã·ã§ã³ãã¯ãã¼ãºããã1761 * FIN を受信したらコネクションをクローズする。 1837 1762 */ 1838 1763 if (flags & TCP_FLG_FIN) 1839 1764 close_connection(cep, &needoutput); 1840 1765 1841 /* åºåãè¡ã£ãå¾çµäºããã*/1766 /* 出力を行った後終了する。*/ 1842 1767 if (needoutput == true || (cep->flags & TCP_CEP_FLG_ACK_NOW)) { 1843 /* éä¿¡ãæ示ããã*/1768 /* 送信を指示する。*/ 1844 1769 cep->flags |= TCP_CEP_FLG_POST_OUTPUT; 1845 1770 sig_sem(SEM_TCP_POST_OUTPUT); … … 1850 1775 reset_drop: 1851 1776 /* 1852 * RST éä¿¡å¦ç1777 * RST 送信処理 1853 1778 */ 1854 1779 … … 1856 1781 goto drop; 1857 1782 1858 /* ãã¹ããªã¼ãã¼ãããããã¯ã¼ã¯ãªã¼ãã¼ã«æ»ãã*/1783 /* ホストオーダーからネットワークオーダーに戻す。*/ 1859 1784 1860 1785 HTONS(tcph->sport); … … 1870 1795 else { 1871 1796 if (tcph->flags & TCP_FLG_SYN) 1872 tcph->sum ++; /* tcph->sum 㯠SDU é·*/1797 tcph->sum ++; /* tcph->sum は SDU 長 */ 1873 1798 tcp_respond(input, cep, tcph->seq + tcph->sum, 0, rbfree, TCP_FLG_RST | TCP_FLG_ACK); 1874 1799 } 1875 1800 1876 /* input 㯠tcp_respoond ã§è¿å´ãããã*/1801 /* input は tcp_respoond で返却される。*/ 1877 1802 NET_COUNT_TCP(net_count_tcp[NC_TCP_SEND_RSTS], 1); 1878 1803 NET_COUNT_MIB(tcp_stats.tcpOutRsts, 1);
Note:
See TracChangeset
for help on using the changeset viewer.