Changeset 321 for EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_input.c
- Timestamp:
- Aug 23, 2017, 9:27:43 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_input.c
- Property svn:keywords deleted
-
Property svn:mime-type
changed from
text/x-csrc
totext/x-csrc;charset=UTF-8
r270 r321 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$ … … 132 120 133 121 /* 134 * æ»ãå¤122 * 戻り値 135 123 * 136 * RET_OK æ£å¸¸137 * RET_DROP ã¨ã©ã¼ãã»ã°ã¡ã³ããç ´æ£ããã138 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã124 * RET_OK 正常 125 * RET_DROP エラー、セグメントを破棄する。 126 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 139 127 */ 140 128 … … 146 134 147 135 /* 148 * é¢æ°136 * 関数 149 137 */ 150 138 … … 165 153 166 154 /* 167 * ã¿ã¹ã¯ããã® Time Wait ç¶æ 168 CEP åé¢æ©è½ 169 */ 170 171 /* 172 * é¢æ° 155 * タスクからの Time Wait 状態 CEP 分離機能 156 */ 157 158 /* 159 * 関数 173 160 */ 174 161 … … 177 164 178 165 /* 179 * å¤æ°166 * 変数 180 167 */ 181 168 … … 183 170 184 171 /* 185 * tcp_find_twcep -- ãã¼ãçªå·ãã Time Wait ç¨ TCP é信端ç¹ãå¾ãã172 * tcp_find_twcep -- ポート番号から Time Wait 用 TCP 通信端点を得る。 186 173 * 187 * 注æ: dstaddr ã¯ããããã¯ã¼ã¯ãã¤ããªã¼ã174 * 注意: dstaddr は、ネットワークバイトオーダ 188 175 */ 189 176 … … 194 181 195 182 /* 196 * ç¶æ 197 ã TIME WAIT ã§ã 198 * IP ã¢ãã¬ã¹ã¨ãã¼ãçªå·ãä¸è´ããé信端ç¹ãæ¢ç´¢ããã 183 * 状態が TIME WAIT で、 184 * IP アドレスとポート番号が一致する通信端点を探索する。 199 185 */ 200 186 for (twcep = &tcp_twcep[NUM_TCP_TW_CEP_ENTRY]; twcep -- != tcp_twcep; ) { … … 211 197 212 198 /* 213 * å¿ 214 è¦ãªæ 215 å ±ã Time Wait ç¨ TCP é信端ç¹ã«ç§»ãã¦ã 216 * æ¨æºã® TCP é信端ç¹ãéæ¾ããã 199 * 必要な情報を Time Wait 用 TCP 通信端点に移して、 200 * 標準の TCP 通信端点を開放する。 217 201 */ 218 202 … … 222 206 T_TCP_TWCEP* twcep; 223 207 224 /* 空ãã® Time Wait ç¨ TCP é信端ç¹ãæ¢ç´¢ããã*/208 /* 空きの Time Wait 用 TCP 通信端点を探索する。*/ 225 209 for (twcep = &tcp_twcep[NUM_TCP_TW_CEP_ENTRY]; twcep -- != tcp_twcep; ) { 226 210 if (twcep->fsm_state != TCP_FSM_TIME_WAIT) { 227 211 228 212 /* 229 * é信端ç¹ãããã¯ãã 230 * å¿ 231 è¦ãªæ 232 å ±ã Time Wait ç¨ TCP é信端ç¹ã«ç§»ãã 213 * 通信端点をロックし、 214 * 必要な情報を Time Wait 用 TCP 通信端点に移す。 233 215 */ 234 216 syscall(wai_sem(cep->semid_lock)); … … 242 224 twcep->timer_2msl = cep->timer[TCP_TIM_2MSL]; 243 225 244 /* é信端ç¹ãããã¯ã解é¤ããã*/226 /* 通信端点をロックを解除する。*/ 245 227 syscall(sig_sem(cep->semid_lock)); 246 228 247 /* æ¨æº TCP é信端ç¹ãéæ¾ããã*/229 /* 標準 TCP 通信端点を開放する。*/ 248 230 tcp_close(cep); 249 231 … … 256 238 257 239 /* 258 * parse_option -- TCP ãããã®ãªãã·ã§ã³ã解æããã240 * parse_option -- TCP ヘッダのオプションを解析する。 259 241 */ 260 242 … … 311 293 312 294 /* 313 * set_rexmt_timer -- æ°ããå¾å¾©æéãåéããåéã¿ã¤ããæ´æ°ããã295 * set_rexmt_timer -- 新しい往復時間を収集し、再送タイマを更新する。 314 296 */ 315 297 … … 322 304 if (cep->srtt != 0) { 323 305 /* 324 * srtt: å¹³æ»åãããRTT306 * srtt: 平滑化された RTT 325 307 * 326 * è¨æ¸¬ããã RTT (rtt) ã¨ç¾å¨ã®å¹³æ»åããã RTT (srtt) ã®å·® (delta) ãæ±ããã308 * 計測された RTT (rtt) と現在の平滑化された RTT (srtt) の差 (delta) を求める。 327 309 * 328 * delta 㯠2 ãããå·¦ã·ãã ( 4 å) ããå¤ã§ä¿æããã329 * srtt 㯠5 ãããå·¦ã·ãã (32 å) ããå¤ã§ä¿æããã¦ããã310 * delta は 2 ビット左シフト ( 4 倍) した値で保持する。 311 * srtt は 5 ビット左シフト (32 倍) した値で保持されている。 330 312 * 331 313 * delta = rtt / 8 - srtt / 8 332 314 * 333 * æ°ãã srtt ã¯315 * 新しい srtt は 334 316 * 335 317 * srtt = rtt / 8 + srtt * 7 / 8 336 318 * = srtt + (rtt / 8 - srtt / 8) 337 319 * 338 * ã§è¨ç®ããã339 * ãã®ãããrtt ã 2 ãããå·¦ã·ããããsrtt ã (5 - 2) ãããå³ã·ããã㦠delta ãæ±ããã320 * で計算する。 321 * このため、rtt を 2 ビット左シフトし、srtt を (5 - 2) ビット右シフトして delta を求める。 340 322 */ 341 323 delta = ((rtt - 1) << TCP_DELTA_SHIFT) - (cep->srtt >> (TCP_SRTT_SHIFT - TCP_DELTA_SHIFT)); … … 345 327 346 328 /* 347 * delta ã®çµ¶å¯¾å¤ | delta | ãæ±ããã329 * delta の絶対値 | delta | を求める。 348 330 */ 349 331 if (delta < 0) … … 351 333 352 334 /* 353 * rttvar: å¹³æ»åãããåæ£335 * rttvar: 平滑化された分散 354 336 * 355 * rttvar 㯠4 ãããå·¦ã·ãã (16 å) ããå¤ã§ä¿æããã¦ããã337 * rttvar は 4 ビット左シフト (16 倍) した値で保持されている。 356 338 * 357 339 * delta = |delta| / 4 - rttvar / 4 358 340 * 359 * æ°ãã rttvar ã¯341 * 新しい rttvar は 360 342 * 361 343 * rttvar = |delta|/ 4 + rttvar * 3 /4 362 344 * = rttvar + (|delta| / 4 - rttvar / 4) 363 345 * 364 * ã§è¨ç®ããã346 * で計算する。 365 347 */ 366 348 delta -= cep->rttvar >> (TCP_RTTVAR_SHIFT - TCP_DELTA_SHIFT); … … 371 353 else { 372 354 /* 373 * ã¾ã srtt ã®è¨å®ãè¡ããã¦ããªãã¨ãã¯ãä»åè¨æ¸¬ããã RTT ã使ç¨ããã374 * å¹³æ»åããã RTT (srtt) ã«ã¯ãRTT ã 5 ãããå·¦ã·ãã (32å) ããå¤ã375 * å¹³æ»åãããåæ£ (rttvar) ã«ã¯ãRTT ã® 1/2 ã 4 ãããå·¦ã·ãã (16å) ããå¤ã355 * まだ srtt の設定が行われていないときは、今回計測された RTT を使用する。 356 * 平滑化された RTT (srtt) には、RTT を 5 ビット左シフト (32倍) した値。 357 * 平滑化された分散 (rttvar) には、RTT の 1/2 を 4 ビット左シフト (16倍) した値。 376 358 */ 377 359 cep->srtt = rtt << TCP_SRTT_SHIFT; … … 380 362 381 363 /* 382 * rtt ã®æ¸¬å®ãçµäºããåéåæ°ããªã»ããããã364 * rtt の測定を終了し、再送回数をリセットする。 383 365 */ 384 366 cep->rtt = cep->rxtshift = 0; 385 367 386 368 /* 387 * RTT ã«è¨±ãããæå°å¤ 㨠rtt + 2 ã®å¤§ããªå¤ã®æ¹ãåéã¿ã¤ã ã¢ã¦ãã®æå°å¤ã«ããã369 * RTT に許される最小値 と rtt + 2 の大きな値の方を再送タイムアウトの最小値にする。 388 370 */ 389 371 if (rtt + 2 < TCP_TVAL_MIN) … … 398 380 399 381 /* 400 * reassemble -- åä¿¡ã»ã°ã¡ã³ããåæ§æãããé çªéãã«åä¿¡ããã¨ãã®å¦ç382 * reassemble -- 受信セグメントを再構成する。順番通りに受信したときの処理 401 383 */ 402 384 … … 410 392 if (tcph->sum > cep->rbufsz - cep->rwbuf_count) { 411 393 /* 412 * åä¿¡ã¦ã£ã³ããããã¡ã«ç©ºãããªãã¨ãã¯ç ´æ£ããã394 * 受信ウィンドバッファに空きがないときは破棄する。 413 395 */ 414 396 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_DROP_SEGS], 1); … … 421 403 cep->fsm_state == TCP_FSM_ESTABLISHED) { 422 404 /* 423 * é çªéãã«ã»ã°ã¡ã³ããåä¿¡ããæã®å¦ç424 * åä¿¡ã»ã°ã¡ã³ãã®ä¸¦ã¹æ¿ãã¯ä¸è¦ãªã®ã§425 * ãã®ã¾ã¾åä¿¡ã¦ã£ã³ããããã¡ã«æ¸ãè¾¼ãã405 * 順番通りにセグメントを受信した時の処理 406 * 受信セグメントの並べ替えは不要なので 407 * そのまま受信ウィンドバッファに書き込む。 426 408 */ 427 409 … … 438 420 qhdr = GET_TCP_Q_HDR(input, thoff); 439 421 440 /* TCP ãããã®ä½ç½®ãä¿åããã*/422 /* TCP ヘッダの位置を保存する。*/ 441 423 GET_TCP_IP_Q_HDR(input)->thoff = thoff; 442 424 443 /* SDU ã®ãªãã»ããï¼å 444 ã¯ã¦ã£ã³ããµã¤ãºï¼ããªã»ããããã*/ 425 /* SDU のオフセット(元はウィンドサイズ)をリセットする。*/ 445 426 qhdr->soff = 0; 446 427 447 /* ãã¼ã¿ãåä¿¡ã¦ã£ã³ããããã¡ã«æ¸ãè¾¼ãã*/428 /* データを受信ウィンドバッファに書き込む。*/ 448 429 TCP_WRITE_RWBUF(cep, input, thoff); 449 430 } … … 456 437 457 438 /* 458 * listening -- ååãªã¼ãã³ãã¦ï¼ç¶æ 459 ã LISTEN ã®å¦ç 439 * listening -- 受動オープンして,状態が LISTEN の処理 460 440 * 461 * æ»ãå¤:462 * RET_OK æ£å¸¸463 * RET_DROP ã¨ã©ã¼ãã»ã°ã¡ã³ããç ´æ£ããã464 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã441 * 戻り値: 442 * RET_OK 正常 443 * RET_DROP エラー、セグメントを破棄する。 444 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 465 445 */ 466 446 … … 475 455 476 456 /* 477 * ãã©ã°ã« RST ãã»ããããã¦ããã°ç ´æ£ããã457 * フラグに RST がセットされていれば破棄する。 478 458 */ 479 459 if (tcph->flags & TCP_FLG_RST) … … 481 461 482 462 /* 483 * ãã©ã°ã« ACK ãã»ãããã¦ãããã°ã484 * ãªã»ãããéã£ã¦ç ´æ£ããã463 * フラグに ACK がセットさてれいれば、 464 * リセットを送って破棄する。 485 465 */ 486 466 if (tcph->flags & TCP_FLG_ACK) … … 488 468 489 469 /* 490 * ãã©ã°ã« SYN ãã»ããããã¦ããªããã°ãã°ç ´æ£ããã470 * フラグに SYN がセットされていなければれば破棄する。 491 471 */ 492 472 if ((tcph->flags & TCP_FLG_SYN) == 0) … … 498 478 499 479 /* 500 * 次ã®ã¨ãã¯ç ´æ£ããã501 * ã»ãã¼ãçªå·ãåä¸ã§ãéåä¿¡ IP ã¢ãã¬ã¹ ãåä¸ã502 * ãã ãããã¼ã«ã«ã«ã¼ããã㯠(127.0.0.1) ãªãè¯ãã503 * ã»ãã«ããã£ã¹ãã¢ãã¬ã¹480 * 次のときは破棄する。 481 * ・ポート番号が同一で、送受信 IP アドレス が同一。 482 * ただし、ローカルループバック (127.0.0.1) なら良い。 483 * ・マルチキャストアドレス 504 484 */ 505 485 … … 511 491 512 492 /* 513 * 次ã®ã¨ãã¯ç ´æ£ããã514 * ã»ãã¼ãçªå·ãåä¸ã§ãéåä¿¡ IP ã¢ãã¬ã¹ ãåä¸ã515 * ã»ãã«ããã£ã¹ãã¢ãã¬ã¹493 * 次のときは破棄する。 494 * ・ポート番号が同一で、送受信 IP アドレス が同一。 495 * ・マルチキャストアドレス 516 496 */ 517 497 … … 526 506 527 507 /* 528 * 次ã®ã¨ãã¯ç ´æ£ããã529 * ã»ãã¼ãçªå·ãåä¸ã§ãéåä¿¡ IP ã¢ãã¬ã¹ ãåä¸ã530 * ã»ãã«ããã£ã¹ãã¢ãã¬ã¹508 * 次のときは破棄する。 509 * ・ポート番号が同一で、送受信 IP アドレス が同一。 510 * ・マルチキャストアドレス 531 511 */ 532 512 … … 539 519 return RET_DROP; 540 520 541 /* ç¸æã®ã¢ãã¬ã¹ãè¨é²ããã*/521 /* 相手のアドレスを記録する。*/ 542 522 IN_COPY_TO_HOST(&cep->dstaddr.ipaddr, &iph->src); 543 523 cep->dstaddr.portno = tcph->sport; 544 524 545 /* ãªãã·ã§ã³ãå¦çããã*/525 /* オプションを処理する。*/ 546 526 parse_option(tcph, cep); 547 527 548 /* ã·ã¼ã±ã³ã¹çªå·ãåæåããã*/528 /* シーケンス番号を初期化する。*/ 549 529 if (tcp_iss == 0) 550 530 tcp_init_iss(); 551 531 552 /* èªåã®ã·ã¼ã±ã³ã¹çªå·ã®åæå¤ãè¨é²ããã*/532 /* 自分のシーケンス番号の初期値を記録する。*/ 553 533 if (iss != 0) 554 534 cep->iss = iss; … … 558 538 tcp_iss += TCP_ISS_INCR() / 4; 559 539 560 /* ç¸æã®ã·ã¼ã±ã³ã¹çªå·ã®åæå¤ãè¨é²ããã*/540 /* 相手のシーケンス番号の初期値を記録する。*/ 561 541 cep->irs = tcph->seq; 562 542 563 /* éåä¿¡ã·ã¼ã±ã³ã¹çªå·ãåæåããã*/543 /* 送受信シーケンス番号を初期化する。*/ 564 544 init_send_seq(cep); 565 545 init_receive_seq(cep); 566 546 567 /* éä¿¡ã¦ã¤ã³ããµã¤ãºãè¨å®ããã*/547 /* 送信ウインドサイズを設定する。*/ 568 548 cep->snd_wnd = tcph->win; 569 549 570 /* æçµè¨å®*/550 /* 最終設定 */ 571 551 cep->flags |= TCP_CEP_FLG_ACK_NOW; 572 552 cep->fsm_state = TCP_FSM_SYN_RECVD; … … 577 557 578 558 /* 579 * syn_sent -- è½åãªã¼ãã³ãã¦ãç¶æ 580 ã SYN éä¿¡æ¸ã®å¦ç 559 * syn_sent -- 能動オープンして、状態が SYN 送信済の処理 581 560 * 582 * æ»ãå¤:583 * RET_OK æ£å¸¸584 * RET_DROP ã¨ã©ã¼ãã»ã°ã¡ã³ããç ´æ£ããã585 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã561 * 戻り値: 562 * RET_OK 正常 563 * RET_DROP エラー、セグメントを破棄する。 564 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 586 565 */ 587 566 … … 592 571 593 572 /* 594 * ç¸æããå信確èªãéããã¦æ¥ã¦ãã573 * 相手から受信確認が送られて来ても、 595 574 * 596 * ACK <= iss && éä¿¡ããæ大SEQ (snd_max) < ACK575 * ACK <= iss && 送信した最大 SEQ (snd_max) < ACK 597 576 * 598 * ãªãããªã»ãããéã£ã¦ã»ã°ã¡ã³ããç ´æ£ããã577 * なら、リセットを送ってセグメントを破棄する。 599 578 */ 600 579 if ((tcph->flags & TCP_FLG_ACK) && … … 603 582 604 583 /* 605 * RST/ACK ãã©ã°ã®å¿çãããã°ããã¼ããéãã¦ããªã606 * ãã¨ãæå³ãã¦ããã584 * RST/ACK フラグの応答があれば、ポートが開いていない 585 * ことを意味している。 607 586 */ 608 587 if (tcph->flags & TCP_FLG_RST) { … … 615 594 616 595 /* 617 * SYN ãã©ã°ããªããã°ã»ã°ã¡ã³ããç ´æ£ããã596 * SYN フラグがなければセグメントを破棄する。 618 597 */ 619 598 if ((tcph->flags & TCP_FLG_SYN) == 0) 620 599 return RET_DROP; 621 600 622 cep->snd_wnd = tcph->win; /* snd_wnd: ç¸æã®åä¿¡å¯è½ã¦ã£ã³ããµã¤ãº*/623 cep->irs = tcph->seq; /* irs: ç¸æã®ã·ã¼ã±ã³ã¹çªå·ã®åæå¤*/624 init_receive_seq(cep); /* éåä¿¡ã·ã¼ã±ã³ã¹çªå·ãåæåããã*/601 cep->snd_wnd = tcph->win; /* snd_wnd: 相手の受信可能ウィンドサイズ */ 602 cep->irs = tcph->seq; /* irs: 相手のシーケンス番号の初期値 */ 603 init_receive_seq(cep); /* 送受信シーケンス番号を初期化する。 */ 625 604 626 605 if (tcph->flags & TCP_FLG_ACK) { 627 606 /* 628 * ACK ãã©ã°ãããã¨ãã®å¦ç607 * ACK フラグがあるときの処理 629 608 * 630 * åä¿¡ãæå¾ 631 ãã¦ããæ大㮠SEQ (rcv_adv) ã 632 * åä¿¡å¯è½ãªã¦ã£ã³ããµã¤ãº (rcv_wnd) åé²ããã 633 */ 634 cep->rcv_adv += cep->rcv_wnd; /* rcv_adv: åä¿¡ãæå¾ 635 ãã¦ããæ大㮠SEQ */ 636 /* rcv_wnd: åä¿¡å¯è½ãªã¦ã£ã³ããµã¤ãº */ 637 638 /* æªç¢ºèªã®æå°éä¿¡ SEQ (snd_una) ã SYN å (1 ãªã¯ããã) é²ããã*/ 609 * 受信を期待している最大の SEQ (rcv_adv) を 610 * 受信可能なウィンドサイズ (rcv_wnd) 分進める。 611 */ 612 cep->rcv_adv += cep->rcv_wnd; /* rcv_adv: 受信を期待している最大の SEQ */ 613 /* rcv_wnd: 受信可能なウィンドサイズ */ 614 615 /* 未確認の最小送信 SEQ (snd_una) を SYN 分 (1 オクテット) 進める。*/ 639 616 cep->snd_una ++; 640 617 641 618 #ifdef TCP_CFG_DELAY_ACK 642 619 643 if (tcph->sum != 0) /* tcph->sum 㯠SDU é·*/620 if (tcph->sum != 0) /* tcph->sum は SDU 長 */ 644 621 cep->flags |= TCP_CEP_FLG_DEL_ACK; 645 622 else … … 654 631 if (cep->flags & TCP_CEP_FLG_NEED_FIN) { 655 632 /* 656 * CEP 㧠FIN éä¿¡ãè¦æ±ããã¦ããã°ã 657 * åæå¦çãéå§ãã 658 * CEP ã®ç¶æ 659 ã FIN Wait 1 ã«ããã 633 * CEP で FIN 送信が要求されていれば、 634 * 切断処理を開始し、 635 * CEP の状態を FIN Wait 1 にする。 660 636 */ 661 637 cep->fsm_state = TCP_FSM_FIN_WAIT_1; … … 665 641 else { 666 642 /* 667 * ç¸æãã ACK ãå¿çãããã®ã§ã 668 * CEP ã®ç¶æ 669 ã ã³ãã¯ã·ã§ã³éè¨å®äºç¶æ 670 ã«ããã 643 * 相手から ACK が応答されたので、 644 * CEP の状態を コネクション開設完了状態にする。 671 645 */ 672 646 cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_IDLE; … … 679 653 if (cep->snd_nblk_tfn == TFN_TCP_CON_CEP) { 680 654 681 /* ç¸æã®ã¢ãã¬ã¹ãã³ãã¼ããã*/655 /* 相手のアドレスをコピーする。*/ 682 656 *cep->p_dstaddr = cep->dstaddr; 683 657 … … 715 689 } 716 690 else { 717 /* ACK ãã©ã°ããªãã¨ãã¯ãACK ãéã£ã¦ãCEP ã®ç¶æ 718 ã SYN åä¿¡æ¸ã¿ã«ããã*/ 691 /* ACK フラグがないときは、ACK を送って、CEP の状態を SYN 受信済みにする。*/ 719 692 cep->flags |= TCP_CEP_FLG_ACK_NOW; 720 693 cep->timer[TCP_TIM_REXMT] = 0; … … 726 699 727 700 /* 728 * trim_length -- åä¿¡ãã SDU é·ã調æ´ããã701 * trim_length -- 受信した SDU 長を調整する。 729 702 */ 730 703 … … 733 706 { 734 707 tcph->seq ++; 735 if (tcph->sum > cep->rcv_wnd) { /* 注æ: tcph->sum 㯠SDU é·*/736 /* 737 * SDU é·ãåä¿¡ã¦ã£ã³ããµã¤ãºãã大ããã¨ãã¯ãåä¿¡ã¦ã£ã³ããµã¤ãºä»¥éã¯738 * ç ´æ£ããFIN ã«å¿çããªããã¨ã§ãç ´æ£ãããã¼ã¿ãåéãããã708 if (tcph->sum > cep->rcv_wnd) { /* 注意: tcph->sum は SDU 長 */ 709 /* 710 * SDU 長が受信ウィンドサイズより大きいときは、受信ウィンドサイズ以降は 711 * 破棄し、FIN に応答しないことで、破棄したデータを再送させる。 739 712 */ 740 713 tcph->sum = (uint16_t)cep->rcv_wnd; 741 714 tcph->flags &= ~TCP_FLG_FIN; 742 715 } 743 cep->snd_wl1 = tcph->seq - 1; /* cep->snd_wl1: ã¦ã£ã³ãæ´æ° SEQ çªå·*/716 cep->snd_wl1 = tcph->seq - 1; /* cep->snd_wl1: ウィンド更新 SEQ 番号 */ 744 717 745 718 #ifdef TCP_CFG_EXTENTIONS 746 cep->rcv_up = tcph->seq; /* cep->rcv_up : åä¿¡ããç·æ¥ãã¤ã³ã¿*/719 cep->rcv_up = tcph->seq; /* cep->rcv_up : 受信した緊急ポインタ */ 747 720 #endif 748 721 } 749 722 750 723 /* 751 * proc_ack2 -- ACK ã®å¦ç(2)724 * proc_ack2 -- ACK の処理 (2) 752 725 * 753 * æ»ãå¤726 * 戻り値 754 727 * 755 * RET_OK æ£å¸¸756 * RET_RETURN æ£å¸¸ããªã¿ã¼ã³ããã757 * RET_DROP ã¨ã©ã¼ãã»ã°ã¡ã³ããç ´æ£ããã758 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã728 * RET_OK 正常 729 * RET_RETURN 正常、リターンする。 730 * RET_DROP エラー、セグメントを破棄する。 731 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 759 732 */ 760 733 … … 770 743 771 744 /* 772 * ç¸æã«å信確èªããã ACK ãããã¾ã 確èªããã¦ããªã773 * æå°éä¿¡ SEQ (snd_una) ãå¼ãã¨ãéä¿¡ã¦ã£ã³ããããã¡ãã774 * åé¤ãã¦ãããªã¯ãããæ° (acked) ã«ãªãã745 * 相手に受信確認された ACK から、まだ確認されていない 746 * 最小送信 SEQ (snd_una) を引くと、送信ウィンドバッファから 747 * 削除してよいオクテット数 (acked) になる。 775 748 */ 776 749 acked = tcph->ack - cep->snd_una; … … 778 751 779 752 /* 780 * å¾å¾©æéè¨æ¸¬ (rtt) ãè¨å®ããã¦ãã¦ãè¨æ¸¬éå§ SEQ ãã781 * å¾ã® ACK ãåä¿¡ããããã¿ã¤ãããã¯ãªãããã£ã³ã»ã«ãã782 * åéã¿ã¤ããåè¨å®ããã753 * 往復時間計測 (rtt) が設定されていて、計測開始 SEQ より 754 * 後の ACK を受信したら、タイマバックオフをキャンセルし、 755 * 再送タイマを再設定する。 783 756 */ 784 757 if (cep->rtt && SEQ_GT(tcph->ack, cep->rtseq)) { … … 787 760 788 761 /* 789 * å 790 ¨ã¦ã®æªç¢ºèªãã¼ã¿ã ACK ãããããåéã¿ã¤ããåæ¢ãã 791 * åéãè¨æ¶ãã (ããã«åºåãæç¶)ã 792 * ãããACK ãã¹ããããã«å¤ãã®ãã¼ã¿ããããªããåéã¿ã¤ãã« 793 * ç¾å¨ã®åéã¿ã¤ã ã¢ã¦ããè¨å®ããã 794 */ 795 if (tcph->ack == cep->snd_max) { /* cep->snd_max: éä¿¡ããæ大 SEQ */ 762 * 全ての未確認データが ACK されたら、再送タイマを停止し、 763 * 再開を記憶する (さらに出力か持続)。 764 * もし、ACK すべき、さらに多くのデータがあるなら、再送タイマに 765 * 現在の再送タイムアウトを設定する。 766 */ 767 if (tcph->ack == cep->snd_max) { /* cep->snd_max: 送信した最大 SEQ */ 796 768 797 769 #ifdef TCP_CFG_SWBUF_CSAVE 798 770 799 771 /* 800 * éä¿¡ã¦ã£ã³ããããã¡ã®çã³ãã¼æ©è½ãæå¹ã®å ´åã¯ã801 * éä¿¡æ¸ã¿ã§ãACKãå®äºããã¾ã§åéã¿ã¤ããå¤æ´ããªãã772 * 送信ウィンドバッファの省コピー機能が有効の場合は、 773 * 送信済みで、ACKが完了するまで再送タイマを変更しない。 802 774 */ 803 775 if ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_ACKED) … … 813 785 } 814 786 else if (cep->timer[TCP_TIM_PERSIST] == 0) { 815 cep->timer[TCP_TIM_REXMT] = cep->rxtcur; /* cep->rxtcur: ç¾å¨ã®åéã¿ã¤ã ã¢ã¦ã*/816 } 817 818 /* ç¸æãå信確èªãããã¼ã¿ãããã¨ãã®å¦ç*/787 cep->timer[TCP_TIM_REXMT] = cep->rxtcur; /* cep->rxtcur: 現在の再送タイムアウト */ 788 } 789 790 /* 相手が受信確認したデータがあるときの処理 */ 819 791 if (acked) { 820 uint32_t cw = cep->snd_cwnd; /* cep->snd_cwnd: 輻輳ã¦ã£ã³ããµã¤ãº*/821 uint32_t incr = cep->maxseg; /* cep->maxseg: æ大ã»ã°ã¡ã³ããµã¤ãº*/822 823 /* 824 * æ°ãã«ç¸æãå信確èªãããã¼ã¿ããã£ãã¨ãã¯ã825 * 輻輳ã¦ã£ã³ããµã¤ãºã大ããããã826 * 輻輳ã¦ã£ã³ããµã¤ãº (snd_cwnd) ã827 * 輻輳ã¦ã£ã³ããµã¤ãºã®ãããå¤ (snd_ssthresh) ãã大ããã¨ãã¯828 * 輻輳åé¿å¶å¾¡ãè¡ãã792 uint32_t cw = cep->snd_cwnd; /* cep->snd_cwnd: 輻輳ウィンドサイズ */ 793 uint32_t incr = cep->maxseg; /* cep->maxseg: 最大セグメントサイズ */ 794 795 /* 796 * 新たに相手が受信確認したデータがあったときは、 797 * 輻輳ウィンドサイズを大きくする。 798 * 輻輳ウィンドサイズ (snd_cwnd) が 799 * 輻輳ウィンドサイズのしきい値 (snd_ssthresh) より大きいときは 800 * 輻輳回避制御を行い。 829 801 * 830 802 * snd_cwnd = snd_cwnd + maxseg * maxseg / snd_cwnd; 831 803 * 832 * çãããå°ããã¨ãã¯ãã¹ãã¼ã¹ã¿ã¼ãå¶å¾¡ãè¡ãã804 * 等しいか小さいときは、スロースタート制御を行う。 833 805 * 834 806 * snd_cwnd = snd_cwnd + maxseg … … 836 808 */ 837 809 if (cw > cep->snd_ssthresh) 838 /* 輻輳åé¿å¶å¾¡*/810 /* 輻輳回避制御 */ 839 811 incr = incr * incr / cw; 840 812 … … 845 817 846 818 /* 847 * éä¿¡ã¦ã£ã³ããããã¡ãããç¸æãå信確èªãããã¼ã¿æ° (acked) ã®ãã¼ã¿ãåé¤ããã819 * 送信ウィンドバッファから、相手が受信確認したデータ数 (acked) のデータを削除する。 848 820 */ 849 821 if (acked > cep->swbuf_count) { … … 858 830 } 859 831 860 /* éä¿¡ã¦ã£ã³ããããã¡ã«ç©ºããã§ãããã¨ãç¥ãããã*/832 /* 送信ウィンドバッファに空きができたことを知らせる。*/ 861 833 syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY)); 862 834 863 835 /* 864 * éé確èªããã¦ããªãæå°éä¿¡ SEQ (snd_una) ã865 * ä»åéé確èªããã ACK ã¾ã§é²ãã866 * 次ã®éä¿¡ãã¼ã¿ã® SEQ (snd_nxt) ããæ°ãã867 * éé確èªããã¦ããªãæå°éä¿¡SEQ (snd_una)868 * ã¾ã§é²ããã836 * 送達確認されていない最小送信 SEQ (snd_una) を 837 * 今回送達確認された ACK まで進め、 838 * 次の送信データの SEQ (snd_nxt) も、新しい 839 * 送達確認されていない最小送信 SEQ (snd_una) 840 * まで進める。 869 841 */ 870 842 cep->snd_una += acked; … … 873 845 874 846 /* 875 * ç¶æ 876 ã«ããåå² 847 * 状態により分岐 877 848 */ 878 849 switch (cep->fsm_state) { 879 case TCP_FSM_FIN_WAIT_1: /* APP ãçµäºãFIN éä¿¡æ¸ã¿ãACK å¾ 880 ã¡ */ 850 case TCP_FSM_FIN_WAIT_1: /* APP が終了、FIN 送信済み、ACK 待ち */ 881 851 if (ourfinisacked) { 882 852 cep->fsm_state = TCP_FSM_FIN_WAIT_2; … … 884 854 } 885 855 break; 886 case TCP_FSM_CLOSING: /* åæã¯ãã¼ãºãFIN 交ææ¸ã¿ãACK å¾ 887 ã¡ */ 856 case TCP_FSM_CLOSING: /* 同時クローズ、FIN 交換済み、ACK 待ち */ 888 857 if (ourfinisacked) { 889 858 /* 890 * éä¿¡ãã FIN ã確èªããã¦ããã°ç¶æ 891 ãå¤æ´ãã 892 * ãã¹ã¦ã®ã¿ã¤ãããªã»ããããå¾ã2MSL ã¿ã¤ããè¨å®ããã 859 * 送信した FIN が確認されていれば状態を変更し、 860 * すべてのタイマをリセットした後、2MSL タイマを設定する。 893 861 */ 894 862 cep->fsm_state = TCP_FSM_TIME_WAIT; … … 897 865 } 898 866 break; 899 case TCP_FSM_LAST_ACK: /* APP ãçµäºãACK å¾ 900 ã¡ */ 867 case TCP_FSM_LAST_ACK: /* APP が終了、ACK 待ち */ 901 868 if (ourfinisacked) { 902 869 /* 903 * éä¿¡ãã FIN ã確èªããã¦ããã°ãcep ãã¯ãã¼ãºãã904 * ã»ã°ã¡ã³ããç ´æ£ããã870 * 送信した FIN が確認されていれば、cep をクローズし、 871 * セグメントを破棄する。 905 872 */ 906 873 cep = tcp_close(cep); … … 908 875 } 909 876 break; 910 case TCP_FSM_TIME_WAIT: /* ç¸æããã® FIN åä¿¡æ¸ã¿ãæéå¾ 911 ã¡ */ 877 case TCP_FSM_TIME_WAIT: /* 相手からの FIN 受信済み、時間待ち */ 912 878 /* 913 * ç¸æãã FIN ãåéããããããä¸åº¦2MSL ã¿ã¤ããè¨å®ãã914 * ACK éä¿¡å¾ãã»ã°ã¡ã³ããç ´æ£ããã879 * 相手から FIN が再送された。もう一度2MSL タイマを設定し、 880 * ACK 送信後、セグメントを破棄する。 915 881 */ 916 882 cep->timer[TCP_TIM_2MSL] = 2 * TCP_TVAL_MSL; … … 923 889 924 890 /* 925 * proc_ack1 -- ACK ã®å¦ç(1)891 * proc_ack1 -- ACK の処理 (1) 926 892 * 927 * æ»ãå¤:928 * RET_OK æ£å¸¸929 * RET_RETURN æ£å¸¸ããªã¿ã¼ã³ããã930 * RET_DROP ã¨ã©ã¼ãã»ã°ã¡ã³ããç ´æ£ããã931 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã893 * 戻り値: 894 * RET_OK 正常 895 * RET_RETURN 正常、リターンする。 896 * RET_DROP エラー、セグメントを破棄する。 897 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 932 898 * 933 899 */ … … 939 905 940 906 switch (cep->fsm_state) { 941 case TCP_FSM_SYN_RECVD: /* SYN ãåä¿¡ããSYN éä¿¡æ¸ã¿ */ 942 943 /* ç¶æ 944 ãå¤æ´ããã*/ 907 case TCP_FSM_SYN_RECVD: /* SYN を受信し、SYN 送信済み */ 908 909 /* 状態を変更する。*/ 945 910 if (cep->flags & TCP_CEP_FLG_NEED_FIN) { 946 911 cep->fsm_state = TCP_FSM_FIN_WAIT_1; … … 951 916 cep->fsm_state = TCP_FSM_ESTABLISHED; 952 917 953 /* TCP é信端ç¹ããTCP åä»å£ã解æ¾ããã*/918 /* TCP 通信端点からTCP 受付口を解放する。*/ 954 919 cep->rep = NULL; 955 920 … … 960 925 if (cep->rcv_nblk_tfn == TFN_TCP_ACP_CEP) { 961 926 962 /* ç¸æã®ã¢ãã¬ã¹ãã³ãã¼ããã*/927 /* 相手のアドレスをコピーする。*/ 963 928 *cep->p_dstaddr = cep->dstaddr; 964 929 … … 996 961 if (cep->snd_nblk_tfn == TFN_TCP_CON_CEP) { 997 962 998 /* ç¸æã®ã¢ãã¬ã¹ãã³ãã¼ããã*/963 /* 相手のアドレスをコピーする。*/ 999 964 *cep->p_dstaddr = cep->dstaddr; 1000 965 … … 1044 1009 1045 1010 /* 1046 * SDU ããªã FIN ãã¤ãã¦ããªããã°ãtcp_move_ra2rw() ãå¼åºãã1047 */ 1048 if (tcph->sum == 0 && (tcph->flags & TCP_FLG_FIN) == 0) /* tcph->sum 㯠SDU é·*/1011 * SDU がなく FIN がついていなければ、tcp_move_ra2rw() を呼出す。 1012 */ 1013 if (tcph->sum == 0 && (tcph->flags & TCP_FLG_FIN) == 0) /* tcph->sum は SDU 長 */ 1049 1014 tcph->flags = tcp_move_ra2rw(cep, tcph->flags); 1050 1015 1051 cep->snd_wl1 = tcph->seq - 1; /* snd_wl1: ã¦ã£ã³ãæ´æ°SEQ */1052 1053 /* break; ä¸ã«è½ã¡ãã*/1016 cep->snd_wl1 = tcph->seq - 1; /* snd_wl1: ウィンド更新 SEQ */ 1017 1018 /* break; 下に落ちる。*/ 1054 1019 1055 case TCP_FSM_ESTABLISHED: /* ã³ãã¯ã·ã§ã³éè¨å®äº */ 1056 case TCP_FSM_FIN_WAIT_1: /* çµäºãã¦ãFIN éä¿¡æ¸ã¿ */ 1057 case TCP_FSM_FIN_WAIT_2: /* çµäºãFIN ä¼é確èªåä¿¡ãFINå¾ 1058 ã¡*/ 1059 case TCP_FSM_CLOSE_WAIT: /* FIN åä¿¡ãã¯ãã¼ãºå¾ 1060 ã¡ */ 1061 case TCP_FSM_CLOSING: /* çµäºãFIN 交ææ¸ã¿ãACK å¾ 1062 ã¡ */ 1063 case TCP_FSM_LAST_ACK: /* FIN åä¿¡ãçµäºãACK å¾ 1064 ã¡ */ 1065 case TCP_FSM_TIME_WAIT: /* çµäºãæéå¾ 1066 ã¡ */ 1020 case TCP_FSM_ESTABLISHED: /* コネクション開設完了 */ 1021 case TCP_FSM_FIN_WAIT_1: /* 終了して、FIN 送信済み */ 1022 case TCP_FSM_FIN_WAIT_2: /* 終了、FIN 伝達確認受信、FIN待ち*/ 1023 case TCP_FSM_CLOSE_WAIT: /* FIN 受信、クローズ待ち */ 1024 case TCP_FSM_CLOSING: /* 終了、FIN 交換済み、ACK 待ち */ 1025 case TCP_FSM_LAST_ACK: /* FIN 受信、終了、ACK 待ち */ 1026 case TCP_FSM_TIME_WAIT: /* 終了、時間待ち */ 1067 1027 1068 1028 if (SEQ_LE(tcph->ack, cep->snd_una)) { 1069 1029 1070 1030 /* 1071 * åä¿¡ç¢ºèª ACK ã æªç¢ºèªã®æå°éä¿¡ SEQ (snd_una) ã¨åãã以åã®ã¨ãã®å¦ç1072 * ã¤ã¾ããå¤éã« ACK ãåä¿¡ãããã¨ãæå³ãã¦ããã1031 * 受信確認 ACK が 未確認の最小送信 SEQ (snd_una) と同じか以前のときの処理 1032 * つまり、多重に ACK を受信したことを意味している。 1073 1033 */ 1074 1034 1075 if (tcph->sum == 0 && tcph->win == cep->snd_wnd) { /* tcph->sum 㯠SDU é·*/1035 if (tcph->sum == 0 && tcph->win == cep->snd_wnd) { /* tcph->sum は SDU 長 */ 1076 1036 1077 1037 /* 1078 * SDU ããªããç¸æã®ã¦ã£ã³ããµã¤ãºãå¤æ´ããã¦ããªããã°ã1079 * ãã§ã«éä¿¡ããã»ã°ã¡ã³ãã®ä¸ã§ãACK (tcph->ack) ã¨1080 * åã SEQ ããå§ã¾ãã»ã°ã¡ã³ãããéä¸ã§æ¶å¤±ããå¯è½æ§ãããã1081 * ãã®å ´åã¯ãé«éå転éã¨é«éãªã«ããªãè¡ãã1038 * SDU がなく、相手のウィンドサイズが変更されていなければ、 1039 * すでに送信したセグメントの中で、ACK (tcph->ack) と 1040 * 同じ SEQ から始まるセグメントが、途中で消失した可能性がある。 1041 * この場合は、高速再転送と高速リカバリを行う。 1082 1042 */ 1083 1043 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_DUP_ACKS], 1); … … 1086 1046 1087 1047 /* 1088 * åéã¿ã¤ããã»ããããã¦ããªãã¨ãã1089 * ã¾ãã¯ãACK (tcph->ack) ã¨æªç¢ºèªã®æå°éä¿¡ SEQã1090 * ä¸è´ããªãã¨ãã¯ãå¤é ACK æ°ã 0 ã«ããã1048 * 再送タイマがセットされていないとき、 1049 * または、ACK (tcph->ack) と未確認の最小送信 SEQが 1050 * 一致しないときは、多重 ACK 数を 0 にする。 1091 1051 */ 1092 1052 cep->dupacks = 0; … … 1096 1056 1097 1057 /* 1098 * å¤é ACK æ°ããããå¤ (æ¨æº 3) ã«ãªã£ãã1099 * é«éå転éå¦çãéå§ããã1058 * 多重 ACK 数がしきい値 (標準 3) になったら 1059 * 高速再転送処理を開始する。 1100 1060 */ 1101 1061 uint_t win; 1102 1062 1103 1063 /* 1104 * 輻輳ã¦ã£ã³ããµã¤ãº(snd_cwnd)ã®ãããå¤ãè¨å®ããã1064 * 輻輳ウィンドサイズ(snd_cwnd)のしきい値を設定する。 1105 1065 * 1106 * ç¸æã®åä¿¡å¯è½ã¦ã£ã³ããµã¤ãº (snd_wnd) ã1107 * 輻輳ã¦ã£ã³ããµã¤ãº (snd_cwnd) ã® 1/2ã1108 * ãã ãã2 * maxseg 以ä¸ã1066 * 相手の受信可能ウィンドサイズ (snd_wnd) か 1067 * 輻輳ウィンドサイズ (snd_cwnd) の 1/2。 1068 * ただし、2 * maxseg 以上。 1109 1069 * 1110 1070 */ … … 1117 1077 cep->snd_ssthresh = win * cep->maxseg; 1118 1078 1119 /* åéã¿ã¤ãã¨å¾å¾©æéããªã»ããããã*/1079 /* 再送タイマと往復時間をリセットする。*/ 1120 1080 cep->timer[TCP_TIM_REXMT] = 0; 1121 1081 cep->rtt = 0; 1122 1082 1123 /* æ¶å¤±ããã»ã°ã¡ã³ããéä¿¡ããã*/1083 /* 消失したセグメントを送信する。*/ 1124 1084 cep->snd_old_nxt = cep->snd_nxt; 1125 1085 cep->snd_nxt = tcph->ack; … … 1127 1087 1128 1088 /* 1129 * snd_nxt ãå 1130 ã«æ»ãããã«è¨å®ã㦠1131 * éä¿¡ãæ示ããã 1089 * snd_nxt を元に戻すように設定して 1090 * 送信を指示する。 1132 1091 */ 1133 1092 cep->flags |= TCP_CEP_FLG_POST_OUTPUT | … … 1137 1096 sig_sem(SEM_TCP_POST_OUTPUT); 1138 1097 1139 /* 輻輳ã¦ã£ã³ããµã¤ãºãæ´æ°ããã*/1098 /* 輻輳ウィンドサイズを更新する。*/ 1140 1099 cep->snd_cwnd = (uint16_t)(cep->snd_ssthresh 1141 1100 + cep->maxseg * cep->dupacks); … … 1147 1106 1148 1107 /* 1149 * å¤é ACK æ°ããããå¤ (æ¨æº 3) ãè¶ 1150 ããã 1151 * 輻輳ã¦ã£ã³ããµã¤ãºãå¢å ããªããåéããã 1108 * 多重 ACK 数がしきい値 (標準 3) を超えたら 1109 * 輻輳ウィンドサイズを増加しながら再送する。 1152 1110 */ 1153 1111 cep->snd_cwnd += cep->maxseg; 1154 1112 1155 /* éä¿¡ãæ示ããã*/1113 /* 送信を指示する。*/ 1156 1114 cep->flags |= TCP_CEP_FLG_POST_OUTPUT; 1157 1115 sig_sem(SEM_TCP_POST_OUTPUT); … … 1166 1124 1167 1125 /* 1168 * åä¿¡ç¢ºèª ACK ã æªç¢ºèªã®æå°éä¿¡ SEQ (snd_una) 以éã®ã¨ãã®å¦ç1126 * 受信確認 ACK が 未確認の最小送信 SEQ (snd_una) 以降のときの処理 1169 1127 */ 1170 1128 if (cep->dupacks >= MAX_TCP_REXMT_THRESH && cep->snd_cwnd > cep->snd_ssthresh) 1171 1129 /* 1172 * é«éå転éãè¡ã£ã¦ããã¨ãã¯ã輻輳ã¦ã£ã³ããµã¤ãºããããå¤ã¾ã§æ»ãã1130 * 高速再転送を行っていたときは、輻輳ウィンドサイズをしきい値まで戻す。 1173 1131 */ 1174 1132 cep->snd_cwnd = (uint16_t)cep->snd_ssthresh; … … 1178 1136 if (SEQ_GT(tcph->ack, cep->snd_max)) 1179 1137 /* 1180 * åä¿¡ãã ACK ãéä¿¡ããæ大 SEQ ãè¶ 1181 ãã¦ããã¨ãã®å¦ç 1138 * 受信した ACK が送信した最大 SEQ を超えていたときの処理 1182 1139 */ 1183 1140 return drop_after_ack(input, cep, thoff); … … 1185 1142 if (cep->flags & TCP_CEP_FLG_NEED_SYN) { 1186 1143 /* 1187 * SYN éä¿¡è¦æ±ãåãæ¶ãã¦ãæªç¢ºèªã®æå°éä¿¡ SEQ ãé²ããã1144 * SYN 送信要求を取り消して、未確認の最小送信 SEQ を進める。 1188 1145 */ 1189 1146 cep->flags &= ~TCP_CEP_FLG_NEED_SYN; … … 1198 1155 1199 1156 /* 1200 * update_wnd -- ã¦ã£ã³ããµã¤ãºãæ´æ°ããã1157 * update_wnd -- ウィンドサイズを更新する。 1201 1158 * 1202 * æ»ãå¤: éä¿¡ãå¿ 1203 è¦ãªã true ãè¿ãã 1159 * 戻り値: 送信が必要なら true を返す。 1204 1160 */ 1205 1161 … … 1209 1165 1210 1166 /* 1211 * æ´æ°æ¡ä»¶1167 * 更新条件 1212 1168 * 1213 * ACK ãã©ã°ãã»ããããã¦ãã&&1214 * ( ååã¦ã£ã³ããæ´æ°ãã SEQ (snd_wl1) ã SEQ ããå||1215 * ååã¦ã£ã³ããæ´æ°ãã SEQ (snd_wl1) ã SEQ ã¨åã&&1216 * ( ååã¦ã£ã³ããæ´æ°ãã ACK (snd_wl2) ã ACK ããå||1217 * ( ååã¦ã£ã³ããæ´æ°ãã ACK (snd_wl2) ã ACK ã¨åã&&1218 * WIN ãç¸æã®åä¿¡å¯è½ã¦ã£ã³ããµã¤ãº (snd_wnd) ãã大ãã1169 * ACK フラグがセットされている && 1170 * (前回ウィンドを更新した SEQ (snd_wl1) が SEQ より前 || 1171 * 前回ウィンドを更新した SEQ (snd_wl1) が SEQ と同じ && 1172 * (前回ウィンドを更新した ACK (snd_wl2) が ACK より前 || 1173 * (前回ウィンドを更新した ACK (snd_wl2) が ACK と同じ && 1174 * WIN が相手の受信可能ウィンドサイズ (snd_wnd) より大きい 1219 1175 * ) 1220 1176 * ) … … 1232 1188 1233 1189 if (cep->snd_wnd > cep->max_sndwnd) 1234 /* ä»ã¾ã§ã®æ大éä¿¡ã¦ã£ã³ããµã¤ãºãæ´æ°ããã*/1190 /* 今までの最大送信ウィンドサイズを更新する。*/ 1235 1191 cep->max_sndwnd = cep->snd_wnd; 1236 1192 … … 1240 1196 1241 1197 /* 1242 * éä¿¡ã¦ã£ã³ããããã¡ç¨ã®ãããã¯ã¼ã¯ãããã¡å²ãå½ã¦ä¸ã§ã 1243 * ç¸æã®åä¿¡ã¦ã£ã³ãã空ãã®ãå¾ 1244 ã£ã¦ããã¨ãã®å¦ç 1198 * 送信ウィンドバッファ用のネットワークバッファ割り当て中で、 1199 * 相手の受信ウィンドが空くのを待っているときの処理 1245 1200 */ 1246 1201 if (cep->snd_wnd > 0) { 1247 1202 1248 1203 /* 1249 * ç¸æã®åä¿¡ã¦ã£ã³ãã空ããã¨ãã¯ã1250 * éä¿¡ã¦ã£ã³ããããã¡ç¨ã®ãããã¯ã¼ã¯ãããã¡å²ãå½ã¦ãåéããã1204 * 相手の受信ウィンドが空いたときは、 1205 * 送信ウィンドバッファ用のネットワークバッファ割り当てを再開する。 1251 1206 */ 1252 1207 cep->flags = (cep->flags & ~TCP_CEP_FLG_WBCS_MASK) … … 1265 1220 1266 1221 /* 1267 * proc_urg -- ç·æ¥ãã¼ã¿ã¤ãã®ã»ã°ã¡ã³ãã®å¦ç1222 * proc_urg -- 緊急データつきのセグメントの処理 1268 1223 */ 1269 1224 … … 1276 1231 TCP_FSM_HAVE_RCVD_FIN(cep->fsm_state) == 0) { 1277 1232 1278 /* ç·æ¥ãã¼ã¿ã¤ãã®ã»ã°ã¡ã³ãã®å¦ç*/1233 /* 緊急データつきのセグメントの処理 */ 1279 1234 1280 1235 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_URG_SEGS], 1); … … 1282 1237 1283 1238 /* 1284 * ç·æ¥ãã¤ã³ã¿ã®ä½ç½®ãåä¿¡ã¦ã£ã³ããããã¡ã® 1285 * ç¯å²ãè¶ 1286 ããã¨ãã¯ä½ãããªãã 1239 * 緊急ポインタの位置が受信ウィンドバッファの 1240 * 範囲を超えるときは何もしない。 1287 1241 */ 1288 1242 tcph->urp = 0; … … 1291 1245 1292 1246 if (SEQ_GT(tcph->seq + tcph->urp, cep->rcv_up)) 1293 /* ç·æ¥ãã¤ã³ã¿ãæ´æ°ãããã¨ãã®å¦ç*/1247 /* 緊急ポインタが更新されたときの処理 */ 1294 1248 cep->rcv_up = tcph->seq + tcph->urp; 1295 1249 1296 if ((tcph->flags & TCP_FLG_URG) && (tcph->urp + TCP_CFG_URG_OFFSET) < tcph->sum) { /* tcph->sum 㯠TCP ã® SDU é·*/1250 if ((tcph->flags & TCP_FLG_URG) && (tcph->urp + TCP_CFG_URG_OFFSET) < tcph->sum) { /* tcph->sum は TCP の SDU 長 */ 1297 1251 1298 1252 /* 1299 * ç·æ¥ãã¤ã³ã¿ã®ä½ç½®ããä»ååä¿¡ããã»ã°ã¡ã³ãå 1300 ã®å ´åã¯ã 1301 * ã³ã¼ã«ããã¯é¢æ°ãå¼ã³åºãã 1253 * 緊急ポインタの位置が、今回受信したセグメント内の場合は、 1254 * コールバック関数を呼び出す。 1302 1255 */ 1303 1256 cep->urg_tcph = tcph; … … 1322 1275 1323 1276 if (cep->urg_tcph != NULL) { 1324 /* ã³ã¼ã«ããã¯é¢æ°å 1325 㧠tcp_rcv_oob() ãå¼åºããªãã£ãã*/ 1277 /* コールバック関数内で tcp_rcv_oob() を呼出さなかった。*/ 1326 1278 cep->urg_tcph = NULL; 1327 1279 tcph->urp = 0; … … 1329 1281 else { 1330 1282 /* 1331 * ã³ã¼ã«ããã¯é¢æ°å 1332 㧠tcp_rcv_oob() ãå¼åºããæã¯ã 1333 * SDU é·ã®è£æ£å¤ãè¨å®ããã 1283 * コールバック関数内で tcp_rcv_oob() を呼出した時は、 1284 * SDU 長の補正値を設定する。 1334 1285 */ 1335 1286 tcph->urp = 1; … … 1358 1309 1359 1310 /* 1360 * drop_after_ack -- åä¿¡ã»ã°ã¡ã³ããç ´æ£ããå¾ãACK ãè¿ã (注æ: ååã¨ã¯åã£ã¦ããªã)ã1311 * drop_after_ack -- 受信セグメントを破棄した後、ACK を返す (注意: 名前とは合っていない)。 1361 1312 * 1362 * æ»ãå¤:1363 * RET_RETURN æ£å¸¸ããªã¿ã¼ã³ããã1364 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã1313 * 戻り値: 1314 * RET_RETURN 正常、リターンする。 1315 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 1365 1316 */ 1366 1317 … … 1371 1322 1372 1323 /* 1373 * SYN åä¿¡ç¶æ 1374 ã§ãACK ãéé確èªããã¦ããªãæå°éä¿¡ SEQ (snd_una) ãã 1375 * åã®å¤ããéä¿¡ãããæ大 SEQ (snd_max) ããå¾ã®å¤ã®å ´åã¯ãç¸æã« RST ã 1376 * éã£ã¦çµäºãããããã¯ã"LAND" DoS æ»æã¸ã®é²å¾¡ã§ãããå½é ããã SYN 1377 * ã»ã°ã¡ã³ããéä¿¡ãã¤ã¥ãããã¼ãéã§ã® ACK ã¹ãã¼ã ãé²ãã 1324 * SYN 受信状態で、ACK が送達確認されていない最小送信 SEQ (snd_una) より 1325 * 前の値か、送信された最大 SEQ (snd_max) より後の値の場合は、相手に RST を 1326 * 送って終了する。これは、"LAND" DoS 攻撃への防御であり、偽造された SYN 1327 * セグメントを送信しつづけるポート間での ACK ストームを防ぐ。 1378 1328 */ 1379 1329 if (cep->fsm_state == TCP_FSM_SYN_RECVD && (tcph->flags & TCP_FLG_ACK) && … … 1384 1334 syscall(rel_net_buf(input)); 1385 1335 1386 /* éä¿¡ãæ示ããã*/1336 /* 送信を指示する。*/ 1387 1337 cep->flags |= TCP_CEP_FLG_ACK_NOW | TCP_CEP_FLG_POST_OUTPUT; 1388 1338 sig_sem(SEM_TCP_POST_OUTPUT); … … 1391 1341 1392 1342 /* 1393 * close_connection -- ã³ãã¯ã·ã§ã³éæ¾å¦çãç¸æãã FIN ãåä¿¡ããã1343 * close_connection -- コネクション開放処理、相手から FIN を受信した。 1394 1344 */ 1395 1345 … … 1416 1366 1417 1367 switch (cep->fsm_state) { 1418 case TCP_FSM_SYN_RECVD: /* SYN ãåä¿¡ããSYN éä¿¡æ¸ã¿*/1419 case TCP_FSM_ESTABLISHED: /* ã³ãã¯ã·ã§ã³éè¨å®äº*/1368 case TCP_FSM_SYN_RECVD: /* SYN を受信し、SYN 送信済み */ 1369 case TCP_FSM_ESTABLISHED: /* コネクション開設完了 */ 1420 1370 cep->fsm_state = TCP_FSM_CLOSE_WAIT; 1421 1371 break; 1422 1372 1423 case TCP_FSM_FIN_WAIT_1: /* APP ãçµäºãFIN éä¿¡æ¸ã¿ãACK å¾ 1424 ã¡ */ 1373 case TCP_FSM_FIN_WAIT_1: /* APP が終了、FIN 送信済み、ACK 待ち */ 1425 1374 cep->fsm_state = TCP_FSM_CLOSING; 1426 1375 break; 1427 1376 1428 case TCP_FSM_FIN_WAIT_2: /* ç¸æããã® FIN å¾ 1429 ã¡ */ 1377 case TCP_FSM_FIN_WAIT_2: /* 相手からの FIN 待ち */ 1430 1378 cep->fsm_state = TCP_FSM_TIME_WAIT; 1431 1379 tcp_cancel_timers(cep); … … 1433 1381 1434 1382 /* 1435 * FIN WAIT 2 ç¶æ 1436 ã§ã¯ã 1437 * åä¿¡ã¯å¯è½ã§ãããããã§ã«éä¿¡ã¯çµäºãã¦ããã 1438 * ç¸æã®éä¿¡ãçµäºããã®ã§ãå 1439 ¥åã¿ã¹ã¯ã®ã¿èµ·åºããã 1383 * FIN WAIT 2 状態では、 1384 * 受信は可能であるが、すでに送信は終了している。 1385 * 相手の送信も終了したので、入力タスクのみ起床する。 1440 1386 */ 1441 1387 syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY)); … … 1443 1389 #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 1444 1390 1445 /* ç¸æããã® FIN ã«å¯¾ãã¦å¿çãè¿ãã*/1391 /* 相手からの FIN に対して応答を返す。*/ 1446 1392 tcp_respond(NULL, cep, cep->rcv_nxt, cep->snd_una, 1447 1393 cep->rbufsz - cep->rwbuf_count, TCP_FLG_ACK); … … 1450 1396 1451 1397 /* 1452 * å¿ 1453 è¦ãªæ 1454 å ±ã Time Wait ç¨ TCP é信端ç¹ã«ç§»ãã¦ã 1455 * æ¨æºã® TCP é信端ç¹ãéæ¾ããã 1398 * 必要な情報を Time Wait 用 TCP 通信端点に移して、 1399 * 標準の TCP 通信端点を開放する。 1456 1400 */ 1457 1401 tcp_move_twcep(cep); … … 1461 1405 break; 1462 1406 1463 case TCP_FSM_TIME_WAIT: /* ç¸æããã® FIN åä¿¡æ¸ã¿ãæéå¾ 1464 ã¡ */ 1407 case TCP_FSM_TIME_WAIT: /* 相手からの FIN 受信済み、時間待ち */ 1465 1408 cep->timer[TCP_TIM_2MSL] = 2 * TCP_TVAL_MSL; 1466 1409 break; … … 1469 1412 1470 1413 /* 1471 * tcp_input -- TCP ã®å 1472 ¥åé¢æ° 1414 * tcp_input -- TCP の入力関数 1473 1415 * 1474 * 注æ: input ã«ã¯ IF ããã㨠IP ããããå 1475 é ã«ããã 1416 * 注意: input には IF ヘッダと IP ヘッダが先頭にある。 1476 1417 */ 1477 1418 … … 1500 1441 NET_COUNT_MIB(tcp_stats.tcpInSegs, 1); 1501 1442 1502 /* ãããé·ããã§ãã¯ããã*/1443 /* ヘッダ長をチェックする。*/ 1503 1444 if (input->len < IF_IP_TCP_HDR_SIZE) { 1504 1445 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_BAD_HEADERS], 1); … … 1509 1450 tcph = GET_TCP_HDR(input, *offp); 1510 1451 1511 seglen = input->len - *offp; /* TCP ã®ã»ã°ã¡ã³ãé·*/1452 seglen = input->len - *offp; /* TCP のセグメント長 */ 1512 1453 1513 1454 if (IN_CKSUM(input, IPPROTO_TCP, *offp, (uint_t)seglen) != 0) { … … 1516 1457 } 1517 1458 1518 /* TCP ãããé·ããã§ãã¯ããã*/1459 /* TCP ヘッダ長をチェックする。*/ 1519 1460 if (TCP_HDR_LEN(tcph->doff) < TCP_HDR_SIZE || TCP_HDR_LEN(tcph->doff) > seglen) { 1520 1461 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_BAD_HEADERS], 1); 1521 1462 goto drop; 1522 1463 } 1523 tcph->sum = seglen - TCP_HDR_LEN(tcph->doff); /* ãããã tcph->sum 㯠TCP ã® SDU é·*/1524 1525 /* 1526 * SYN 㨠FIN ã®ä¸¡ããããã»ããããã¦ããã°ç ´æ£ãããnmap çã®å¯¾ç1527 * ãã ããRFC1644 T/TCP æ¡å¼µæ©è½ã¨ç«¶åããã1464 tcph->sum = seglen - TCP_HDR_LEN(tcph->doff); /* ここから tcph->sum は TCP の SDU 長 */ 1465 1466 /* 1467 * SYN と FIN の両ビットがセットされていれば破棄する。nmap 等の対策 1468 * ただし、RFC1644 T/TCP 拡張機能と競合する。 1528 1469 */ 1529 1470 if ((tcph->flags & (TCP_FLG_SYN | TCP_FLG_FIN)) == (TCP_FLG_SYN | TCP_FLG_FIN)) 1530 1471 goto drop; 1531 1472 1532 /* ãããã¯ã¼ã¯ãªã¼ãã¼ãããã¹ããªã¼ãã¼ã«å¤æããã*/1473 /* ネットワークオーダーからホストオーダーに変換する。*/ 1533 1474 1534 1475 NTOHL(tcph->seq); … … 1544 1485 1545 1486 /* 1546 * ç¶æ 1547 ã Time Wait ä¸ã® CEP ãæ¢ç´¢ããã 1487 * 状態が Time Wait 中の CEP を探索する。 1548 1488 */ 1549 1489 twcep = tcp_find_twcep(&iph->dst, tcph->dport, &iph->src, tcph->sport); 1550 1490 if (twcep != NULL) { 1551 1491 1552 if (tcph->flags & TCP_FLG_RST) /* RST ãã©ã°ãåä¿¡ããã¨ãã¯ç¡è¦ããã*/1492 if (tcph->flags & TCP_FLG_RST) /* RST フラグを受信したときは無視する。*/ 1553 1493 goto drop; 1554 1494 else { 1555 1495 1556 1496 /* 1557 * TCP é信端ç¹ã Time Wait ã®æãç¸æãã¹ãããã»ã°ã¡ã³ããæ¥ãã¨ãã¯ã1558 * ç¸æãã¹ãã® FIN ã«å¯¾ããèªãã¹ãã® ACK ã»ã°ã¡ã³ããéä¸ã§1559 * æ失ãããã¨ãæå³ãã¦ããã®ã§ãACK ã»ã°ã¡ã³ããåéããã1497 * TCP 通信端点が Time Wait の時、相手ホストからセグメントが来たときは、 1498 * 相手ホストの FIN に対する自ホストの ACK セグメントが途中で 1499 * 損失したことを意味しているので、ACK セグメントを再送する。 1560 1500 */ 1561 1501 1562 /* ãã¹ããªã¼ãã¼ãããããã¯ã¼ã¯ãªã¼ãã¼ã«æ»ãã*/1502 /* ホストオーダーからネットワークオーダーに戻す。*/ 1563 1503 HTONS(tcph->sport); 1564 1504 HTONS(tcph->dport); … … 1569 1509 } 1570 1510 else 1571 /* æ¨æºã® TCP é信端ç¹ãå¾ãã*/1511 /* 標準の TCP 通信端点を得る。*/ 1572 1512 cep = tcp_find_cep(&iph->dst, tcph->dport, &iph->src, tcph->sport); 1573 1513 1574 1514 #else /* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */ 1575 1515 1576 /* TCP é信端ç¹ãå¾ãã*/1516 /* TCP 通信端点を得る。*/ 1577 1517 cep = tcp_find_cep(&iph->dst, tcph->dport, &iph->src, tcph->sport); 1578 1518 … … 1580 1520 1581 1521 /* 1582 * TCP é信端ç¹ããªãå ´å㨠CEP ã®ç¶æ 1583 ãã¯ãã¼ãºãªãç ´æ£ããã 1522 * TCP 通信端点がない場合と CEP の状態がクローズなら破棄する。 1584 1523 */ 1585 1524 if (cep == NULL) { … … 1599 1538 1600 1539 /* 1601 * ã³ãã¯ã·ã§ã³éè¨æ¸ã¿ã§ã»ã°ã¡ã³ããåä¿¡ããã¨ãã¯ã1602 * ã¢ã¤ãã«æéã¨çå確èªã¿ã¤ãããªã»ããããã1540 * コネクション開設済みでセグメントを受信したときは、 1541 * アイドル時間と生存確認タイマをリセットする。 1603 1542 */ 1604 1543 cep->idle = 0; … … 1607 1546 } 1608 1547 1609 /* CEP ã®ç¶æ 1610 ã LISTEN 以å¤ã®æã¯ããªãã·ã§ã³ãå¦çããã*/ 1548 /* CEP の状態が LISTEN 以外の時は、オプションを処理する。*/ 1611 1549 if (cep->fsm_state != TCP_FSM_LISTEN) 1612 1550 parse_option(tcph, cep); 1613 1551 1614 1552 /* 1615 * åä¿¡å¯è½ã¦ã£ã³ããµã¤ãºãè¨ç®ããã1553 * 受信可能ウィンドサイズを計算する。 1616 1554 * 1617 * rcv_nxt: åä¿¡ãæå¾ 1618 ãã¦ããæå°ã® SEQï¼ãã以åã¯åä¿¡æ¸ã¿ï¼ 1619 * rcv_adv: åä¿¡ãæå¾ 1620 ãã¦ããæ大㮠SEQ 1621 * rbufsz: åä¿¡ã¦ã£ã³ããããã¡ãµã¤ãº 1622 * rwbuf_count: åä¿¡ã¦ã£ã³ããããã¡ã«ãããã¼ã¿é 1623 * tcph->sum: ä»ååä¿¡ãã SDU ãµã¤ãº 1555 * rcv_nxt: 受信を期待している最小の SEQ(これ以前は受信済み) 1556 * rcv_adv: 受信を期待している最大の SEQ 1557 * rbufsz: 受信ウィンドバッファサイズ 1558 * rwbuf_count: 受信ウィンドバッファにあるデータ量 1559 * tcph->sum: 今回受信した SDU サイズ 1624 1560 * 1625 * ä»ååä¿¡ããã»ã°ã¡ã³ããé åºæ´åãã¥ã¼ã«é£çµãã 1626 * å¯è½æ§ãããã®ã§ tcph->sum ãèæ 1627 ®ããã 1561 * 今回受信したセグメントを順序整列キューに連結する 1562 * 可能性があるので tcph->sum を考慮する。 1628 1563 * 1629 1564 */ … … 1636 1571 cep->rcv_wnd = cep->rcv_adv - cep->rcv_nxt; 1637 1572 1638 /* CEP ã®ç¶æ 1639 ã«ããå¦çãè¡ãã*/ 1640 1641 if (cep->fsm_state == TCP_FSM_LISTEN) { /* ååãªã¼ãã³ (LISTEN) ã®å¦çã*/ 1573 /* CEP の状態により処理を行う。*/ 1574 1575 if (cep->fsm_state == TCP_FSM_LISTEN) { /* 受動オープン (LISTEN) の処理。*/ 1642 1576 if ((ret = listening(input, cep, *offp, iss)) == RET_RST_DROP) 1643 1577 goto reset_drop; 1644 1578 else if (ret == RET_DROP) 1645 1579 goto drop; 1646 trim_length(tcph, cep); /* åä¿¡ãã SDU é·ã調æ´ããã*/1647 1648 if (tcph->flags & TCP_FLG_ACK) { /* ACK ãã©ã°ã®å¦ç*/1580 trim_length(tcph, cep); /* 受信した SDU 長を調整する。*/ 1581 1582 if (tcph->flags & TCP_FLG_ACK) { /* ACK フラグの処理 */ 1649 1583 if ((ret = proc_ack2(input, cep, *offp, &needoutput)) == RET_DROP) 1650 1584 goto drop; … … 1655 1589 } 1656 1590 } 1657 else if (cep->fsm_state == TCP_FSM_SYN_SENT) { /* è½åãªã¼ãã³ãSYN éä¿¡æ¸ã¿*/1591 else if (cep->fsm_state == TCP_FSM_SYN_SENT) { /* 能動オープン、SYN 送信済み */ 1658 1592 if ((ret = syn_sent(tcph, cep)) == RET_RST_DROP) 1659 1593 goto reset_drop; 1660 1594 else if (ret == RET_DROP) 1661 1595 goto drop; 1662 trim_length(tcph, cep); /* åä¿¡ãã SDU é·ã調æ´ããã*/1663 1664 if (tcph->flags & TCP_FLG_ACK) { /* ACK ãã©ã°ã®å¦ç*/1596 trim_length(tcph, cep); /* 受信した SDU 長を調整する。*/ 1597 1598 if (tcph->flags & TCP_FLG_ACK) { /* ACK フラグの処理 */ 1665 1599 if ((ret = proc_ack2(input, cep, *offp, &needoutput)) == RET_DROP) 1666 1600 goto drop; … … 1672 1606 } 1673 1607 else { 1674 if (cep->fsm_state == TCP_FSM_SYN_RECVD) { /* SYN ãåä¿¡ãSYN éä¿¡æ¸ã¿*/1608 if (cep->fsm_state == TCP_FSM_SYN_RECVD) { /* SYN を受信、SYN 送信済み */ 1675 1609 /* 1676 * ç¸æããå信確èªãéããã¦æ¥ã¦ãã1610 * 相手から受信確認が送られて来ても、 1677 1611 * 1678 * ACK <= æªç¢ºèªã®æå°éä¿¡SEQ (snd_una) &&1679 * éä¿¡ããæ大SEQ (snd_max) < ACK1612 * ACK <= 未確認の最小送信 SEQ (snd_una) && 1613 * 送信した最大 SEQ (snd_max) < ACK 1680 1614 * 1681 * ãªãããªã»ãããéã£ã¦ã»ã°ã¡ã³ããç ´æ£ããã1615 * なら、リセットを送ってセグメントを破棄する。 1682 1616 */ 1683 1617 if ((tcph->flags & TCP_FLG_ACK) && … … 1688 1622 1689 1623 /* 1690 * RST ãã©ã°ãåä¿¡ããã¨ãã®å¦ç (ç°å¸¸åæ)1624 * RST フラグを受信したときの処理 (異常切断) 1691 1625 */ 1692 1626 if (tcph->flags & TCP_FLG_RST) { … … 1694 1628 SEQ_LT(tcph->seq, cep->last_ack_sent + cep->rcv_wnd)) { 1695 1629 /* 1696 * åä¿¡ããã»ã°ã¡ã³ãã® SEQ ããæå¾ã«éä¿¡ããACK (last_ack_sent)1697 * ãããåä¿¡ã¦ã¤ã³ãã¦ãµã¤ãºã¾ã§ã®éã®å¦ç1630 * 受信したセグメントの SEQ が、最後に送信した ACK (last_ack_sent) 1631 * から、受信ウインドウサイズまでの間の処理 1698 1632 */ 1699 1633 switch (cep->fsm_state) { 1700 case TCP_FSM_SYN_RECVD: /* SYN ãåä¿¡ããSYN éä¿¡æ¸ã¿*/1701 1702 cep->net_error = EV_CNNRF; /* æ¥ç¶ä¸è½*/1634 case TCP_FSM_SYN_RECVD: /* SYN を受信し、SYN 送信済み */ 1635 1636 cep->net_error = EV_CNNRF; /* 接続不能 */ 1703 1637 cep->error = E_CLS; 1704 1638 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_RSTS], 1); … … 1707 1641 break; 1708 1642 1709 case TCP_FSM_ESTABLISHED: /* ã³ãã¯ã·ã§ã³éè¨å®äº */ 1710 case TCP_FSM_CLOSE_WAIT: /* FIN åä¿¡ãã¯ãã¼ãºå¾ 1711 ã¡ */ 1643 case TCP_FSM_ESTABLISHED: /* コネクション開設完了 */ 1644 case TCP_FSM_CLOSE_WAIT: /* FIN 受信、クローズ待ち */ 1712 1645 NET_COUNT_MIB(tcp_stats.tcpEstabResets, 1); 1713 1646 /* fallthrough */ 1714 1647 1715 case TCP_FSM_FIN_WAIT_1: /* çµäºãã¦ãFIN éä¿¡æ¸ã¿ */ 1716 case TCP_FSM_FIN_WAIT_2: /* çµäºãFIN ä¼é確èªåä¿¡ãFINå¾ 1717 ã¡ */ 1718 1719 cep->net_error = EV_CNRST; /* æ¥ç¶ãªã»ãã */ 1648 case TCP_FSM_FIN_WAIT_1: /* 終了して、FIN 送信済み */ 1649 case TCP_FSM_FIN_WAIT_2: /* 終了、FIN 伝達確認受信、FIN待ち */ 1650 1651 cep->net_error = EV_CNRST; /* 接続リセット */ 1720 1652 cep->error = E_CLS; 1721 1653 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_RSTS], 1); 1722 1654 /* no break; */ 1723 1655 1724 case TCP_FSM_CLOSING: /* çµäºãFIN 交ææ¸ã¿ãACK å¾ 1725 ã¡ */ 1726 case TCP_FSM_LAST_ACK: /* FIN åä¿¡ãçµäºãACK å¾ 1727 ã¡ */ 1656 case TCP_FSM_CLOSING: /* 終了、FIN 交換済み、ACK 待ち */ 1657 case TCP_FSM_LAST_ACK: /* FIN 受信、終了、ACK 待ち */ 1728 1658 1729 1659 cep = tcp_close(cep); … … 1735 1665 1736 1666 /* 1737 * CEP ã®ç¶æ 1738 ã SYN ãåä¿¡ããSYN éä¿¡æ¸ã¿ã®å ´åã¯ã 1739 * åä¿¡ã¦ã£ã³ãã«åã¾ãããã«ãã¼ã¿ã 1740 * 調æ´ããåã«ããã®æ¥ç¶ã«ãããã±ãããã©ãããæ¤è¨¼ããã 1667 * CEP の状態が SYN を受信し、SYN 送信済みの場合は、 1668 * 受信ウィンドに収まるようにデータを 1669 * 調整する前に、この接続によるパケットかどうかを検証する。 1741 1670 * 1742 * åä¿¡ããç¸æã® SEQ < ç¸æã® SEQ ã®åæå¤(irs)1671 * 受信した相手の SEQ < 相手の SEQ の初期値 (irs) 1743 1672 * 1744 * ããã¯ã"LAND" DoS æ»æã®é²å¾¡ã§ããã1673 * これは、"LAND" DoS 攻撃の防御である。 1745 1674 */ 1746 1675 if (cep->fsm_state == TCP_FSM_SYN_RECVD && SEQ_LT(tcph->seq, cep->irs)) { … … 1749 1678 1750 1679 /* 1751 * åä¿¡ãæå¾ 1752 ãã¦ããæå°ã® SEQ (rcv_nxt) - åä¿¡ããç¸æã® SEQ ã 1753 * æ£ãªããrcv_nxt 以åã®ãã¼ã¿ã¯ãã§ã«åä¿¡ãã¦ããã®ã§ããã®é¨åã 1754 * åé¤ããã 1680 * 受信を期待している最小の SEQ (rcv_nxt) - 受信した相手の SEQ が 1681 * 正なら、rcv_nxt 以前のデータはすでに受信しているので、その部分を 1682 * 削除する。 1755 1683 * <---------- rcv_wnd ---------> 1756 1684 * rcv_nxt rcv_nxt + rcv_wnd … … 1764 1692 * ^ ^ 1765 1693 * seq seq + len 1766 * <---------------> åé¤ããã1694 * <---------------> 削除する。 1767 1695 */ 1768 1696 todrop = cep->rcv_nxt - tcph->seq; … … 1770 1698 1771 1699 /* 1772 * SYN ãã©ã°ãã¤ãã¦ããã¨ãã¯ããã®å (1 ãªã¯ããã)1773 * SEQ ãé²ããç·æ¥ãã¤ã³ã¿ã¨åé¤ããé·ãã調æ´ããã1700 * SYN フラグがついているときは、その分 (1 オクテット) 1701 * SEQ を進め、緊急ポインタと削除する長さを調整する。 1774 1702 */ 1775 1703 if (tcph->flags & TCP_FLG_SYN) { … … 1784 1712 1785 1713 /* 1786 * åé¤ããé·ãã SDU ããé·ããã¤ã¾ããåä¿¡ãæå¾ 1787 ãã¦ãã 1788 * æå°ã® SEQ (rcv_nxt) ã«éãã¦ããªããã 1789 * åé¤ããé·ãã SDU ã¨åãã§ãFIN ãã©ã°ãã¤ãã¦ãªããã° 1790 * å 1791 ¨ã¦åé¤ããã 1714 * 削除する長さが SDU より長い、つまり、受信を期待している 1715 * 最小の SEQ (rcv_nxt) に達していないか、 1716 * 削除する長さが SDU と同じで、FIN フラグがついてなければ 1717 * 全て削除する。 1792 1718 */ 1793 if ( todrop > tcph->sum || /* tcph->sum 㯠TCP ã® SDU é·*/1719 if ( todrop > tcph->sum || /* tcph->sum は TCP の SDU 長 */ 1794 1720 (todrop == tcph->sum && (tcph->flags & TCP_FLG_FIN) == 0)) { 1795 1721 tcph->flags &= ~TCP_FLG_FIN; 1796 1722 cep->flags |= TCP_CEP_FLG_ACK_NOW; 1797 todrop = tcph->sum; /* tcph->sum 㯠TCP ã® SDU é·*/1723 todrop = tcph->sum; /* tcph->sum は TCP の SDU 長 */ 1798 1724 } 1799 1725 1800 1726 /* 1801 * SDU ãåã«è©°ããã1727 * SDU を前に詰める。 1802 1728 */ 1803 if (todrop < tcph->sum) { /* tcph->sum 㯠TCP ã® SDU é·*/1729 if (todrop < tcph->sum) { /* tcph->sum は TCP の SDU 長 */ 1804 1730 memcpy(GET_TCP_SDU(input, *offp), 1805 1731 GET_TCP_SDU(input, *offp) + todrop, (size_t)(tcph->sum - todrop)); … … 1807 1733 1808 1734 /* 1809 * SEQ 㨠SDU é·ã調æ´ããã1735 * SEQ と SDU 長を調整する。 1810 1736 */ 1811 1737 tcph->seq += todrop; 1812 tcph->sum -= (uint16_t)todrop; /* tcph->sum 㯠TCP ã® SDU é·*/1738 tcph->sum -= (uint16_t)todrop; /* tcph->sum は TCP の SDU 長 */ 1813 1739 1814 1740 /* 1815 * ç·æ¥ãã¤ã³ã¿ã調æ´ããã1741 * 緊急ポインタを調整する。 1816 1742 */ 1817 1743 if (tcph->urp > todrop) … … 1826 1752 1827 1753 /* 1828 * ããã¦ã¼ã¶ã¿ã¹ã¯ãçµäºããå¾ã«ããã¼ã¿ãåä¿¡ãã1829 * å ´åã¯ãRST ãéãã1830 */ 1831 if (cep->fsm_state == TCP_FSM_LAST_ACK && tcph->sum > 0) { /* tcph->sum 㯠TCP ã® SDU é·*/1754 * もしユーザタスクが終了した後に、データを受信した 1755 * 場合は、RST を送る。 1756 */ 1757 if (cep->fsm_state == TCP_FSM_LAST_ACK && tcph->sum > 0) { /* tcph->sum は TCP の SDU 長 */ 1832 1758 cep = tcp_close(cep); 1833 1759 goto reset_drop; … … 1835 1761 1836 1762 /* 1837 * åä¿¡ã»ã°ã¡ã³ããåä¿¡ã¦ã£ã³ããè¶ 1838 ããå ´åã¯ã 1839 * è¶ 1840 ããåãåãã 1763 * 受信セグメントが受信ウィンドを超える場合は、 1764 * 超えた分を削る。 1841 1765 * 1842 1766 * <---------- rcv_wnd ---------> … … 1851 1775 * ^ ^ 1852 1776 * seq seq + len 1853 * <-----> åé¤ããã1854 */ 1855 todrop = (tcph->seq + tcph->sum) - (cep->rcv_nxt + cep->rcv_wnd); /* tcph->sum 㯠TCP ã® SDU é·*/1777 * <-----> 削除する。 1778 */ 1779 todrop = (tcph->seq + tcph->sum) - (cep->rcv_nxt + cep->rcv_wnd); /* tcph->sum は TCP の SDU 長 */ 1856 1780 if (todrop > 0) { 1857 if (todrop > tcph->sum) { /* tcph->sum 㯠TCP ã® SDU é·*/1781 if (todrop > tcph->sum) { /* tcph->sum は TCP の SDU 長 */ 1858 1782 /* 1859 * åä¿¡ãã SDU ã®å 1860 ¨ã¦ãåä¿¡ã¦ã£ã³ããè¶ 1861 ããå ´åã 1783 * 受信した SDU の全てが受信ウィンドを超える場合。 1862 1784 * 1863 * TIME_WAIT ä¸ã«ãæ°ããªæ¥ç¶è¦æ±ãåä¿¡ããã1864 * å¤ãæ¥ç¶ãç ´æ£ããæ°ããªæ¥ç¶ãéå§ããã1865 * ãã ããSEQ ã¯åããé²ãã§ããªããã°ãªããªãã1785 * TIME_WAIT 中に、新たな接続要求を受信したら 1786 * 古い接続を破棄し、新たな接続を開始する。 1787 * ただし、SEQ は前より進んでいなければならない。 1866 1788 */ 1867 1789 if ((tcph->flags & TCP_FLG_SYN) && … … 1875 1797 1876 1798 /* 1877 * åä¿¡ã¦ã£ã³ãã 0 ã§ãåä¿¡ãã SEQ 㨠1878 * åä¿¡ãæå¾ 1879 ãã¦ããæå°ã® SEQ ãä¸è´ããã¨ã㯠1880 * ACK ãè¿ãããã以å¤ã¯ãã¼ã¿ãç ´æ£ããACK ãè¿ãã 1799 * 受信ウィンドが 0 で、受信した SEQ と 1800 * 受信を期待している最小の SEQ が一致したときは 1801 * ACK を返す。それ以外はデータを破棄し、ACK を返す。 1881 1802 */ 1882 1803 if (cep->rcv_wnd == 0 && (tcph->seq == cep->rcv_nxt || tcph->sum == 0)) { … … 1889 1810 } 1890 1811 } 1891 tcph->sum -= (uint16_t)todrop; /* tcph->sum 㯠TCP ã® SDU é·*/1812 tcph->sum -= (uint16_t)todrop; /* tcph->sum は TCP の SDU 長 */ 1892 1813 tcph->flags &= ~(TCP_FLG_PUSH | TCP_FLG_FIN); 1893 1814 } 1894 1815 1895 1816 /* 1896 * ãããSYN ãã»ããããã¦ããã°ã1897 * ã¨ã©ã¼ãªã®ã§ RST ãéããæ¥ç¶ãç ´æ£ããã1817 * もし、SYN がセットされていれば、 1818 * エラーなので RST を送り、接続を破棄する。 1898 1819 */ 1899 1820 if (tcph->flags & TCP_FLG_SYN) { … … 1904 1825 1905 1826 /* 1906 * ãããACK ãã»ããããã¦ããªãå ´åã¯ã 1907 * ç¶æ 1908 ã SYN åä¿¡æ¸ã¿ã 1909 * SYN ãéä¿¡ãããã¨ãã¦ããã°ãå¦çãç¶ãããã 1910 * ãã以å¤ã¯ã»ã°ã¡ã³ããç ´æ£ãã¦çµäºããã 1827 * もし、ACK がセットされていない場合は、 1828 * 状態が SYN 受信済みか 1829 * SYN を送信しようとしていれば、処理を続けるが、 1830 * それ以外はセグメントを破棄して終了する。 1911 1831 */ 1912 1832 if ((tcph->flags & TCP_FLG_ACK) == 0) { … … 1916 1836 else { 1917 1837 /* 1918 * ACK ã®å¦ç1838 * ACK の処理 1919 1839 */ 1920 1840 ret = proc_ack1(input, cep, *offp, &needoutput); … … 1930 1850 /* step 6 */ 1931 1851 1932 /* éä¿¡ã¦ã£ã³ããæ´æ°ããã*/1852 /* 送信ウィンドを更新する。*/ 1933 1853 if (update_wnd(tcph, cep) == true) 1934 1854 needoutput = true; 1935 1855 1936 /* ç·æ¥ãã¼ã¿ãå¦çããã*/1856 /* 緊急データを処理する。*/ 1937 1857 proc_urg(tcph, cep); 1938 1858 … … 1940 1860 1941 1861 /* 1942 * SDU ãããããFIN ãæªåä¿¡ã®ç¶æ 1943 ã§ãæåã« FIN ãåä¿¡ããã¨ãã 1944 * åä¿¡ã»ã°ã¡ã³ããã¥ã¼ã« net_buf ã追å ããã 1945 * ãã以å¤ã®å ´åã¯ãã»ã°ã¡ã³ããç ´æ£ããã 1862 * SDU があるか、FIN を未受信の状態で、最初に FIN を受信したとき、 1863 * 受信セグメントキューに net_buf を追加する。 1864 * それ以外の場合は、セグメントを破棄する。 1946 1865 */ 1947 1866 flags = tcph->flags; 1948 if ((tcph->sum > 0 || (flags & TCP_FLG_FIN)) && /* tcph->sum 㯠TCP ã® SDU é·*/1867 if ((tcph->sum > 0 || (flags & TCP_FLG_FIN)) && /* tcph->sum は TCP の SDU 長 */ 1949 1868 TCP_FSM_HAVE_RCVD_FIN(cep->fsm_state) == 0) { 1950 1869 flags = reassemble(input, cep, *offp, flags); … … 1956 1875 1957 1876 /* 1958 * FIN ãåä¿¡ãããã³ãã¯ã·ã§ã³ãã¯ãã¼ãºããã1877 * FIN を受信したらコネクションをクローズする。 1959 1878 */ 1960 1879 if (flags & TCP_FLG_FIN) 1961 1880 close_connection(cep, &needoutput); 1962 1881 1963 /* åºåãè¡ã£ãå¾çµäºããã*/1882 /* 出力を行った後終了する。*/ 1964 1883 if (needoutput == true || (cep->flags & TCP_CEP_FLG_ACK_NOW)) { 1965 /* éä¿¡ãæ示ããã*/1884 /* 送信を指示する。*/ 1966 1885 cep->flags |= TCP_CEP_FLG_POST_OUTPUT; 1967 1886 sig_sem(SEM_TCP_POST_OUTPUT); … … 1972 1891 reset_drop: 1973 1892 /* 1974 * RST éä¿¡å¦ç1893 * RST 送信処理 1975 1894 */ 1976 1895 … … 1978 1897 goto drop; 1979 1898 1980 /* ãã¹ããªã¼ãã¼ãããããã¯ã¼ã¯ãªã¼ãã¼ã«æ»ãã*/1899 /* ホストオーダーからネットワークオーダーに戻す。*/ 1981 1900 1982 1901 HTONS(tcph->sport); … … 1993 1912 else { 1994 1913 if (tcph->flags & TCP_FLG_SYN) 1995 tcph->sum ++; /* tcph->sum 㯠SDU é·*/1914 tcph->sum ++; /* tcph->sum は SDU 長 */ 1996 1915 tcp_respond(input, cep, tcph->seq + tcph->sum, 0, rbfree, TCP_FLG_RST | TCP_FLG_ACK); 1997 1916 } 1998 1917 1999 /* input 㯠tcp_respoond ã§è¿å´ãããã*/1918 /* input は tcp_respoond で返却される。*/ 2000 1919 NET_COUNT_TCP(net_count_tcp[NC_TCP_SEND_RSTS], 1); 2001 1920 NET_COUNT_MIB(tcp_stats.tcpOutRsts, 1);
Note:
See TracChangeset
for help on using the changeset viewer.