Changeset 389 for azure_iot_hub/trunk/asp3_dcre/tinet/netinet/tcp_input.c
- Timestamp:
- May 22, 2019, 10:03:37 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
azure_iot_hub/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
r388 r389 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 544 524 #if defined(_IP6_CFG) && defined(_IP4_CFG) … … 590 570 } 591 571 else { 592 /* ACK ãã©ã°ããªãã¨ãã¯ãACK ãéã£ã¦ãCEP ã®ç¶æ 593 ã SYN åä¿¡æ¸ã¿ã«ããã*/ 572 /* ACK フラグがないときは、ACK を送って、CEP の状態を SYN 受信済みにする。*/ 594 573 cep->flags |= TCP_CEP_FLG_ACK_NOW; 595 574 cep->timer[TCP_TIM_REXMT] = 0; … … 601 580 602 581 /* 603 * trim_length -- åä¿¡ãã SDU é·ã調æ´ããã582 * trim_length -- 受信した SDU 長を調整する。 604 583 */ 605 584 … … 608 587 { 609 588 tcph->seq ++; 610 if (tcph->sum > cep->rcv_wnd) { /* 注æ: tcph->sum 㯠SDU é·*/611 /* 612 * SDU é·ãåä¿¡ã¦ã£ã³ããµã¤ãºãã大ããã¨ãã¯ãåä¿¡ã¦ã£ã³ããµã¤ãºä»¥éã¯613 * ç ´æ£ããFIN ã«å¿çããªããã¨ã§ãç ´æ£ãããã¼ã¿ãåéãããã589 if (tcph->sum > cep->rcv_wnd) { /* 注意: tcph->sum は SDU 長 */ 590 /* 591 * SDU 長が受信ウィンドサイズより大きいときは、受信ウィンドサイズ以降は 592 * 破棄し、FIN に応答しないことで、破棄したデータを再送させる。 614 593 */ 615 594 tcph->sum = (uint16_t)cep->rcv_wnd; 616 595 tcph->flags &= ~TCP_FLG_FIN; 617 596 } 618 cep->snd_wl1 = tcph->seq - 1; /* cep->snd_wl1: ã¦ã£ã³ãæ´æ° SEQ çªå·*/597 cep->snd_wl1 = tcph->seq - 1; /* cep->snd_wl1: ウィンド更新 SEQ 番号 */ 619 598 620 599 #ifdef TCP_CFG_EXTENTIONS 621 cep->rcv_up = tcph->seq; /* cep->rcv_up : åä¿¡ããç·æ¥ãã¤ã³ã¿*/600 cep->rcv_up = tcph->seq; /* cep->rcv_up : 受信した緊急ポインタ */ 622 601 #endif 623 602 } 624 603 625 604 /* 626 * proc_ack2 -- ACK ã®å¦ç(2)605 * proc_ack2 -- ACK の処理 (2) 627 606 * 628 * æ»ãå¤607 * 戻り値 629 608 * 630 * RET_OK æ£å¸¸631 * RET_RETURN æ£å¸¸ããªã¿ã¼ã³ããã632 * RET_DROP ã¨ã©ã¼ãã»ã°ã¡ã³ããç ´æ£ããã633 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã609 * RET_OK 正常 610 * RET_RETURN 正常、リターンする。 611 * RET_DROP エラー、セグメントを破棄する。 612 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 634 613 */ 635 614 … … 645 624 646 625 /* 647 * ç¸æã«å信確èªããã ACK ãããã¾ã 確èªããã¦ããªã648 * æå°éä¿¡ SEQ (snd_una) ãå¼ãã¨ãéä¿¡ã¦ã£ã³ããããã¡ãã649 * åé¤ãã¦ãããªã¯ãããæ° (acked) ã«ãªãã626 * 相手に受信確認された ACK から、まだ確認されていない 627 * 最小送信 SEQ (snd_una) を引くと、送信ウィンドバッファから 628 * 削除してよいオクテット数 (acked) になる。 650 629 */ 651 630 acked = tcph->ack - cep->snd_una; … … 653 632 654 633 /* 655 * å¾å¾©æéè¨æ¸¬ (rtt) ãè¨å®ããã¦ãã¦ãè¨æ¸¬éå§ SEQ ãã656 * å¾ã® ACK ãåä¿¡ããããã¿ã¤ãããã¯ãªãããã£ã³ã»ã«ãã657 * åéã¿ã¤ããåè¨å®ããã634 * 往復時間計測 (rtt) が設定されていて、計測開始 SEQ より 635 * 後の ACK を受信したら、タイマバックオフをキャンセルし、 636 * 再送タイマを再設定する。 658 637 */ 659 638 if (cep->rtt && SEQ_GT(tcph->ack, cep->rtseq)) { … … 662 641 663 642 /* 664 * å 665 ¨ã¦ã®æªç¢ºèªãã¼ã¿ã ACK ãããããåéã¿ã¤ããåæ¢ãã 666 * åéãè¨æ¶ãã (ããã«åºåãæç¶)ã 667 * ãããACK ãã¹ããããã«å¤ãã®ãã¼ã¿ããããªããåéã¿ã¤ãã« 668 * ç¾å¨ã®åéã¿ã¤ã ã¢ã¦ããè¨å®ããã 669 */ 670 if (tcph->ack == cep->snd_max) { /* cep->snd_max: éä¿¡ããæ大 SEQ */ 643 * 全ての未確認データが ACK されたら、再送タイマを停止し、 644 * 再開を記憶する (さらに出力か持続)。 645 * もし、ACK すべき、さらに多くのデータがあるなら、再送タイマに 646 * 現在の再送タイムアウトを設定する。 647 */ 648 if (tcph->ack == cep->snd_max) { /* cep->snd_max: 送信した最大 SEQ */ 671 649 672 650 #ifdef TCP_CFG_SWBUF_CSAVE 673 651 674 652 /* 675 * éä¿¡ã¦ã£ã³ããããã¡ã®çã³ãã¼æ©è½ãæå¹ã®å ´åã¯ã676 * éä¿¡æ¸ã¿ã§ãACKãå®äºããã¾ã§åéã¿ã¤ããå¤æ´ããªãã653 * 送信ウィンドバッファの省コピー機能が有効の場合は、 654 * 送信済みで、ACKが完了するまで再送タイマを変更しない。 677 655 */ 678 656 if ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_ACKED) … … 688 666 } 689 667 else if (cep->timer[TCP_TIM_PERSIST] == 0) { 690 cep->timer[TCP_TIM_REXMT] = cep->rxtcur; /* cep->rxtcur: ç¾å¨ã®åéã¿ã¤ã ã¢ã¦ã*/691 } 692 693 /* ç¸æãå信確èªãããã¼ã¿ãããã¨ãã®å¦ç*/668 cep->timer[TCP_TIM_REXMT] = cep->rxtcur; /* cep->rxtcur: 現在の再送タイムアウト */ 669 } 670 671 /* 相手が受信確認したデータがあるときの処理 */ 694 672 if (acked) { 695 uint32_t cw = cep->snd_cwnd; /* cep->snd_cwnd: 輻輳ã¦ã£ã³ããµã¤ãº*/696 uint32_t incr = cep->maxseg; /* cep->maxseg: æ大ã»ã°ã¡ã³ããµã¤ãº*/697 698 /* 699 * æ°ãã«ç¸æãå信確èªãããã¼ã¿ããã£ãã¨ãã¯ã700 * 輻輳ã¦ã£ã³ããµã¤ãºã大ããããã701 * 輻輳ã¦ã£ã³ããµã¤ãº (snd_cwnd) ã702 * 輻輳ã¦ã£ã³ããµã¤ãºã®ãããå¤ (snd_ssthresh) ãã大ããã¨ãã¯703 * 輻輳åé¿å¶å¾¡ãè¡ãã673 uint32_t cw = cep->snd_cwnd; /* cep->snd_cwnd: 輻輳ウィンドサイズ */ 674 uint32_t incr = cep->maxseg; /* cep->maxseg: 最大セグメントサイズ */ 675 676 /* 677 * 新たに相手が受信確認したデータがあったときは、 678 * 輻輳ウィンドサイズを大きくする。 679 * 輻輳ウィンドサイズ (snd_cwnd) が 680 * 輻輳ウィンドサイズのしきい値 (snd_ssthresh) より大きいときは 681 * 輻輳回避制御を行い。 704 682 * 705 683 * snd_cwnd = snd_cwnd + maxseg * maxseg / snd_cwnd; 706 684 * 707 * çãããå°ããã¨ãã¯ãã¹ãã¼ã¹ã¿ã¼ãå¶å¾¡ãè¡ãã685 * 等しいか小さいときは、スロースタート制御を行う。 708 686 * 709 687 * snd_cwnd = snd_cwnd + maxseg … … 711 689 */ 712 690 if (cw > cep->snd_ssthresh) 713 /* 輻輳åé¿å¶å¾¡*/691 /* 輻輳回避制御 */ 714 692 incr = incr * incr / cw; 715 693 … … 720 698 721 699 /* 722 * éä¿¡ã¦ã£ã³ããããã¡ãããç¸æãå信確èªãããã¼ã¿æ° (acked) ã®ãã¼ã¿ãåé¤ããã700 * 送信ウィンドバッファから、相手が受信確認したデータ数 (acked) のデータを削除する。 723 701 */ 724 702 if (acked > cep->swbuf_count) { … … 733 711 } 734 712 735 /* éä¿¡ã¦ã£ã³ããããã¡ã«ç©ºããã§ãããã¨ãç¥ãããã*/713 /* 送信ウィンドバッファに空きができたことを知らせる。*/ 736 714 syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY)); 737 715 738 716 /* 739 * éé確èªããã¦ããªãæå°éä¿¡ SEQ (snd_una) ã740 * ä»åéé確èªããã ACK ã¾ã§é²ãã741 * 次ã®éä¿¡ãã¼ã¿ã® SEQ (snd_nxt) ããæ°ãã742 * éé確èªããã¦ããªãæå°éä¿¡SEQ (snd_una)743 * ã¾ã§é²ããã717 * 送達確認されていない最小送信 SEQ (snd_una) を 718 * 今回送達確認された ACK まで進め、 719 * 次の送信データの SEQ (snd_nxt) も、新しい 720 * 送達確認されていない最小送信 SEQ (snd_una) 721 * まで進める。 744 722 */ 745 723 cep->snd_una += acked; … … 748 726 749 727 /* 750 * ç¶æ 751 ã«ããåå² 728 * 状態により分岐 752 729 */ 753 730 switch (cep->fsm_state) { 754 case TCP_FSM_FIN_WAIT_1: /* APP ãçµäºãFIN éä¿¡æ¸ã¿ãACK å¾ 755 ã¡ */ 731 case TCP_FSM_FIN_WAIT_1: /* APP が終了、FIN 送信済み、ACK 待ち */ 756 732 if (ourfinisacked) { 757 733 cep->fsm_state = TCP_FSM_FIN_WAIT_2; … … 759 735 } 760 736 break; 761 case TCP_FSM_CLOSING: /* åæã¯ãã¼ãºãFIN 交ææ¸ã¿ãACK å¾ 762 ã¡ */ 737 case TCP_FSM_CLOSING: /* 同時クローズ、FIN 交換済み、ACK 待ち */ 763 738 if (ourfinisacked) { 764 739 /* 765 * éä¿¡ãã FIN ã確èªããã¦ããã°ç¶æ 766 ãå¤æ´ãã 767 * ãã¹ã¦ã®ã¿ã¤ãããªã»ããããå¾ã2MSL ã¿ã¤ããè¨å®ããã 740 * 送信した FIN が確認されていれば状態を変更し、 741 * すべてのタイマをリセットした後、2MSL タイマを設定する。 768 742 */ 769 743 cep->fsm_state = TCP_FSM_TIME_WAIT; … … 772 746 } 773 747 break; 774 case TCP_FSM_LAST_ACK: /* APP ãçµäºãACK å¾ 775 ã¡ */ 748 case TCP_FSM_LAST_ACK: /* APP が終了、ACK 待ち */ 776 749 if (ourfinisacked) { 777 750 /* 778 * éä¿¡ãã FIN ã確èªããã¦ããã°ãcep ãã¯ãã¼ãºãã779 * ã»ã°ã¡ã³ããç ´æ£ããã751 * 送信した FIN が確認されていれば、cep をクローズし、 752 * セグメントを破棄する。 780 753 */ 781 754 cep = tcp_close(cep); … … 783 756 } 784 757 break; 785 case TCP_FSM_TIME_WAIT: /* ç¸æããã® FIN åä¿¡æ¸ã¿ãæéå¾ 786 ã¡ */ 758 case TCP_FSM_TIME_WAIT: /* 相手からの FIN 受信済み、時間待ち */ 787 759 /* 788 * ç¸æãã FIN ãåéããããããä¸åº¦2MSL ã¿ã¤ããè¨å®ãã789 * ACK éä¿¡å¾ãã»ã°ã¡ã³ããç ´æ£ããã760 * 相手から FIN が再送された。もう一度2MSL タイマを設定し、 761 * ACK 送信後、セグメントを破棄する。 790 762 */ 791 763 cep->timer[TCP_TIM_2MSL] = 2 * TCP_TVAL_MSL; … … 798 770 799 771 /* 800 * proc_ack1 -- ACK ã®å¦ç(1)772 * proc_ack1 -- ACK の処理 (1) 801 773 * 802 * æ»ãå¤:803 * RET_OK æ£å¸¸804 * RET_RETURN æ£å¸¸ããªã¿ã¼ã³ããã805 * RET_DROP ã¨ã©ã¼ãã»ã°ã¡ã³ããç ´æ£ããã806 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã774 * 戻り値: 775 * RET_OK 正常 776 * RET_RETURN 正常、リターンする。 777 * RET_DROP エラー、セグメントを破棄する。 778 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 807 779 * 808 780 */ … … 814 786 815 787 switch (cep->fsm_state) { 816 case TCP_FSM_SYN_RECVD: /* SYN ãåä¿¡ããSYN éä¿¡æ¸ã¿ */ 817 818 /* ç¶æ 819 ãå¤æ´ããã*/ 788 case TCP_FSM_SYN_RECVD: /* SYN を受信し、SYN 送信済み */ 789 790 /* 状態を変更する。*/ 820 791 if (cep->flags & TCP_CEP_FLG_NEED_FIN) { 821 792 cep->fsm_state = TCP_FSM_FIN_WAIT_1; … … 826 797 cep->fsm_state = TCP_FSM_ESTABLISHED; 827 798 828 /* TCP é信端ç¹ããTCP åä»å£ã解æ¾ããã*/799 /* TCP 通信端点からTCP 受付口を解放する。*/ 829 800 cep->rep = NULL; 830 801 … … 839 810 if (cep->rcv_nblk_tfn == TFN_TCP_ACP_CEP) { 840 811 841 /* ç¸æã®ã¢ãã¬ã¹ãã³ãã¼ããã*/812 /* 相手のアドレスをコピーする。*/ 842 813 843 814 #if defined(_IP6_CFG) && defined(_IP4_CFG) … … 889 860 if (cep->snd_nblk_tfn == TFN_TCP_CON_CEP) { 890 861 891 /* ç¸æã®ã¢ãã¬ã¹ãã³ãã¼ããã*/862 /* 相手のアドレスをコピーする。*/ 892 863 893 864 #if defined(_IP6_CFG) && defined(_IP4_CFG) … … 951 922 952 923 /* 953 * SDU ããªã FIN ãã¤ãã¦ããªããã°ãtcp_move_ra2rw() ãå¼åºãã954 */ 955 if (tcph->sum == 0 && (tcph->flags & TCP_FLG_FIN) == 0) /* tcph->sum 㯠SDU é·*/924 * SDU がなく FIN がついていなければ、tcp_move_ra2rw() を呼出す。 925 */ 926 if (tcph->sum == 0 && (tcph->flags & TCP_FLG_FIN) == 0) /* tcph->sum は SDU 長 */ 956 927 tcph->flags = tcp_move_ra2rw(cep, tcph->flags); 957 928 958 cep->snd_wl1 = tcph->seq - 1; /* snd_wl1: ã¦ã£ã³ãæ´æ°SEQ */959 960 /* break; ä¸ã«è½ã¡ãã*/929 cep->snd_wl1 = tcph->seq - 1; /* snd_wl1: ウィンド更新 SEQ */ 930 931 /* break; 下に落ちる。*/ 961 932 962 case TCP_FSM_ESTABLISHED: /* ã³ãã¯ã·ã§ã³éè¨å®äº */ 963 case TCP_FSM_FIN_WAIT_1: /* çµäºãã¦ãFIN éä¿¡æ¸ã¿ */ 964 case TCP_FSM_FIN_WAIT_2: /* çµäºãFIN ä¼é確èªåä¿¡ãFINå¾ 965 ã¡*/ 966 case TCP_FSM_CLOSE_WAIT: /* FIN åä¿¡ãã¯ãã¼ãºå¾ 967 ã¡ */ 968 case TCP_FSM_CLOSING: /* çµäºãFIN 交ææ¸ã¿ãACK å¾ 969 ã¡ */ 970 case TCP_FSM_LAST_ACK: /* FIN åä¿¡ãçµäºãACK å¾ 971 ã¡ */ 972 case TCP_FSM_TIME_WAIT: /* çµäºãæéå¾ 973 ã¡ */ 933 case TCP_FSM_ESTABLISHED: /* コネクション開設完了 */ 934 case TCP_FSM_FIN_WAIT_1: /* 終了して、FIN 送信済み */ 935 case TCP_FSM_FIN_WAIT_2: /* 終了、FIN 伝達確認受信、FIN待ち*/ 936 case TCP_FSM_CLOSE_WAIT: /* FIN 受信、クローズ待ち */ 937 case TCP_FSM_CLOSING: /* 終了、FIN 交換済み、ACK 待ち */ 938 case TCP_FSM_LAST_ACK: /* FIN 受信、終了、ACK 待ち */ 939 case TCP_FSM_TIME_WAIT: /* 終了、時間待ち */ 974 940 975 941 if (SEQ_LE(tcph->ack, cep->snd_una)) { 976 942 977 943 /* 978 * åä¿¡ç¢ºèª ACK ã æªç¢ºèªã®æå°éä¿¡ SEQ (snd_una) ã¨åãã以åã®ã¨ãã®å¦ç979 * ã¤ã¾ããå¤éã« ACK ãåä¿¡ãããã¨ãæå³ãã¦ããã944 * 受信確認 ACK が 未確認の最小送信 SEQ (snd_una) と同じか以前のときの処理 945 * つまり、多重に ACK を受信したことを意味している。 980 946 */ 981 947 982 if (tcph->sum == 0 && tcph->win == cep->snd_wnd) { /* tcph->sum 㯠SDU é·*/948 if (tcph->sum == 0 && tcph->win == cep->snd_wnd) { /* tcph->sum は SDU 長 */ 983 949 984 950 /* 985 * SDU ããªããç¸æã®ã¦ã£ã³ããµã¤ãºãå¤æ´ããã¦ããªããã°ã986 * ãã§ã«éä¿¡ããã»ã°ã¡ã³ãã®ä¸ã§ãACK (tcph->ack) ã¨987 * åã SEQ ããå§ã¾ãã»ã°ã¡ã³ãããéä¸ã§æ¶å¤±ããå¯è½æ§ãããã988 * ãã®å ´åã¯ãé«éå転éã¨é«éãªã«ããªãè¡ãã951 * SDU がなく、相手のウィンドサイズが変更されていなければ、 952 * すでに送信したセグメントの中で、ACK (tcph->ack) と 953 * 同じ SEQ から始まるセグメントが、途中で消失した可能性がある。 954 * この場合は、高速再転送と高速リカバリを行う。 989 955 */ 990 956 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_DUP_ACKS], 1); … … 993 959 994 960 /* 995 * åéã¿ã¤ããã»ããããã¦ããªãã¨ãã996 * ã¾ãã¯ãACK (tcph->ack) ã¨æªç¢ºèªã®æå°éä¿¡ SEQã997 * ä¸è´ããªãã¨ãã¯ãå¤é ACK æ°ã 0 ã«ããã961 * 再送タイマがセットされていないとき、 962 * または、ACK (tcph->ack) と未確認の最小送信 SEQが 963 * 一致しないときは、多重 ACK 数を 0 にする。 998 964 */ 999 965 cep->dupacks = 0; … … 1003 969 1004 970 /* 1005 * å¤é ACK æ°ããããå¤ (æ¨æº 3) ã«ãªã£ãã1006 * é«éå転éå¦çãéå§ããã971 * 多重 ACK 数がしきい値 (標準 3) になったら 972 * 高速再転送処理を開始する。 1007 973 */ 1008 974 uint_t win; 1009 975 1010 976 /* 1011 * 輻輳ã¦ã£ã³ããµã¤ãº(snd_cwnd)ã®ãããå¤ãè¨å®ããã977 * 輻輳ウィンドサイズ(snd_cwnd)のしきい値を設定する。 1012 978 * 1013 * ç¸æã®åä¿¡å¯è½ã¦ã£ã³ããµã¤ãº (snd_wnd) ã1014 * 輻輳ã¦ã£ã³ããµã¤ãº (snd_cwnd) ã® 1/2ã1015 * ãã ãã2 * maxseg 以ä¸ã979 * 相手の受信可能ウィンドサイズ (snd_wnd) か 980 * 輻輳ウィンドサイズ (snd_cwnd) の 1/2。 981 * ただし、2 * maxseg 以上。 1016 982 * 1017 983 */ … … 1024 990 cep->snd_ssthresh = win * cep->maxseg; 1025 991 1026 /* åéã¿ã¤ãã¨å¾å¾©æéããªã»ããããã*/992 /* 再送タイマと往復時間をリセットする。*/ 1027 993 cep->timer[TCP_TIM_REXMT] = 0; 1028 994 cep->rtt = 0; 1029 995 1030 /* æ¶å¤±ããã»ã°ã¡ã³ããéä¿¡ããã*/996 /* 消失したセグメントを送信する。*/ 1031 997 cep->snd_old_nxt = cep->snd_nxt; 1032 998 cep->snd_nxt = tcph->ack; … … 1034 1000 1035 1001 /* 1036 * snd_nxt ãå 1037 ã«æ»ãããã«è¨å®ã㦠1038 * éä¿¡ãæ示ããã 1002 * snd_nxt を元に戻すように設定して 1003 * 送信を指示する。 1039 1004 */ 1040 1005 cep->flags |= TCP_CEP_FLG_POST_OUTPUT | … … 1044 1009 sig_sem(SEM_TCP_POST_OUTPUT); 1045 1010 1046 /* 輻輳ã¦ã£ã³ããµã¤ãºãæ´æ°ããã*/1011 /* 輻輳ウィンドサイズを更新する。*/ 1047 1012 cep->snd_cwnd = (uint16_t)(cep->snd_ssthresh 1048 1013 + cep->maxseg * cep->dupacks); … … 1054 1019 1055 1020 /* 1056 * å¤é ACK æ°ããããå¤ (æ¨æº 3) ãè¶ 1057 ããã 1058 * 輻輳ã¦ã£ã³ããµã¤ãºãå¢å ããªããåéããã 1021 * 多重 ACK 数がしきい値 (標準 3) を超えたら 1022 * 輻輳ウィンドサイズを増加しながら再送する。 1059 1023 */ 1060 1024 cep->snd_cwnd += cep->maxseg; 1061 1025 1062 /* éä¿¡ãæ示ããã*/1026 /* 送信を指示する。*/ 1063 1027 cep->flags |= TCP_CEP_FLG_POST_OUTPUT; 1064 1028 sig_sem(SEM_TCP_POST_OUTPUT); … … 1073 1037 1074 1038 /* 1075 * åä¿¡ç¢ºèª ACK ã æªç¢ºèªã®æå°éä¿¡ SEQ (snd_una) 以éã®ã¨ãã®å¦ç1039 * 受信確認 ACK が 未確認の最小送信 SEQ (snd_una) 以降のときの処理 1076 1040 */ 1077 1041 if (cep->dupacks >= MAX_TCP_REXMT_THRESH && cep->snd_cwnd > cep->snd_ssthresh) 1078 1042 /* 1079 * é«éå転éãè¡ã£ã¦ããã¨ãã¯ã輻輳ã¦ã£ã³ããµã¤ãºããããå¤ã¾ã§æ»ãã1043 * 高速再転送を行っていたときは、輻輳ウィンドサイズをしきい値まで戻す。 1080 1044 */ 1081 1045 cep->snd_cwnd = (uint16_t)cep->snd_ssthresh; … … 1085 1049 if (SEQ_GT(tcph->ack, cep->snd_max)) 1086 1050 /* 1087 * åä¿¡ãã ACK ãéä¿¡ããæ大 SEQ ãè¶ 1088 ãã¦ããã¨ãã®å¦ç 1051 * 受信した ACK が送信した最大 SEQ を超えていたときの処理 1089 1052 */ 1090 1053 return drop_after_ack(input, cep, thoff); … … 1092 1055 if (cep->flags & TCP_CEP_FLG_NEED_SYN) { 1093 1056 /* 1094 * SYN éä¿¡è¦æ±ãåãæ¶ãã¦ãæªç¢ºèªã®æå°éä¿¡ SEQ ãé²ããã1057 * SYN 送信要求を取り消して、未確認の最小送信 SEQ を進める。 1095 1058 */ 1096 1059 cep->flags &= ~TCP_CEP_FLG_NEED_SYN; … … 1105 1068 1106 1069 /* 1107 * update_wnd -- ã¦ã£ã³ããµã¤ãºãæ´æ°ããã1070 * update_wnd -- ウィンドサイズを更新する。 1108 1071 * 1109 * æ»ãå¤: éä¿¡ãå¿ 1110 è¦ãªã true ãè¿ãã 1072 * 戻り値: 送信が必要なら true を返す。 1111 1073 */ 1112 1074 … … 1116 1078 1117 1079 /* 1118 * æ´æ°æ¡ä»¶1080 * 更新条件 1119 1081 * 1120 * ACK ãã©ã°ãã»ããããã¦ãã&&1121 * ( ååã¦ã£ã³ããæ´æ°ãã SEQ (snd_wl1) ã SEQ ããå||1122 * ååã¦ã£ã³ããæ´æ°ãã SEQ (snd_wl1) ã SEQ ã¨åã&&1123 * ( ååã¦ã£ã³ããæ´æ°ãã ACK (snd_wl2) ã ACK ããå||1124 * ( ååã¦ã£ã³ããæ´æ°ãã ACK (snd_wl2) ã ACK ã¨åã&&1125 * WIN ãç¸æã®åä¿¡å¯è½ã¦ã£ã³ããµã¤ãº (snd_wnd) ãã大ãã1082 * ACK フラグがセットされている && 1083 * (前回ウィンドを更新した SEQ (snd_wl1) が SEQ より前 || 1084 * 前回ウィンドを更新した SEQ (snd_wl1) が SEQ と同じ && 1085 * (前回ウィンドを更新した ACK (snd_wl2) が ACK より前 || 1086 * (前回ウィンドを更新した ACK (snd_wl2) が ACK と同じ && 1087 * WIN が相手の受信可能ウィンドサイズ (snd_wnd) より大きい 1126 1088 * ) 1127 1089 * ) … … 1139 1101 1140 1102 if (cep->snd_wnd > cep->max_sndwnd) 1141 /* ä»ã¾ã§ã®æ大éä¿¡ã¦ã£ã³ããµã¤ãºãæ´æ°ããã*/1103 /* 今までの最大送信ウィンドサイズを更新する。*/ 1142 1104 cep->max_sndwnd = cep->snd_wnd; 1143 1105 … … 1147 1109 1148 1110 /* 1149 * éä¿¡ã¦ã£ã³ããããã¡ç¨ã®ãããã¯ã¼ã¯ãããã¡å²ãå½ã¦ä¸ã§ã 1150 * ç¸æã®åä¿¡ã¦ã£ã³ãã空ãã®ãå¾ 1151 ã£ã¦ããã¨ãã®å¦ç 1111 * 送信ウィンドバッファ用のネットワークバッファ割り当て中で、 1112 * 相手の受信ウィンドが空くのを待っているときの処理 1152 1113 */ 1153 1114 if (cep->snd_wnd > 0) { 1154 1115 1155 1116 /* 1156 * ç¸æã®åä¿¡ã¦ã£ã³ãã空ããã¨ãã¯ã1157 * éä¿¡ã¦ã£ã³ããããã¡ç¨ã®ãããã¯ã¼ã¯ãããã¡å²ãå½ã¦ãåéããã1117 * 相手の受信ウィンドが空いたときは、 1118 * 送信ウィンドバッファ用のネットワークバッファ割り当てを再開する。 1158 1119 */ 1159 1120 cep->flags = (cep->flags & ~TCP_CEP_FLG_WBCS_MASK) … … 1172 1133 1173 1134 /* 1174 * proc_urg -- ç·æ¥ãã¼ã¿ã¤ãã®ã»ã°ã¡ã³ãã®å¦ç1135 * proc_urg -- 緊急データつきのセグメントの処理 1175 1136 */ 1176 1137 … … 1183 1144 TCP_FSM_HAVE_RCVD_FIN(cep->fsm_state) == 0) { 1184 1145 1185 /* ç·æ¥ãã¼ã¿ã¤ãã®ã»ã°ã¡ã³ãã®å¦ç*/1146 /* 緊急データつきのセグメントの処理 */ 1186 1147 1187 1148 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_URG_SEGS], 1); … … 1189 1150 1190 1151 /* 1191 * ç·æ¥ãã¤ã³ã¿ã®ä½ç½®ãåä¿¡ã¦ã£ã³ããããã¡ã® 1192 * ç¯å²ãè¶ 1193 ããã¨ãã¯ä½ãããªãã 1152 * 緊急ポインタの位置が受信ウィンドバッファの 1153 * 範囲を超えるときは何もしない。 1194 1154 */ 1195 1155 tcph->urp = 0; … … 1198 1158 1199 1159 if (SEQ_GT(tcph->seq + tcph->urp, cep->rcv_up)) 1200 /* ç·æ¥ãã¤ã³ã¿ãæ´æ°ãããã¨ãã®å¦ç*/1160 /* 緊急ポインタが更新されたときの処理 */ 1201 1161 cep->rcv_up = tcph->seq + tcph->urp; 1202 1162 1203 if ((tcph->flags & TCP_FLG_URG) && (tcph->urp + TCP_CFG_URG_OFFSET) < tcph->sum) { /* tcph->sum 㯠TCP ã® SDU é·*/1163 if ((tcph->flags & TCP_FLG_URG) && (tcph->urp + TCP_CFG_URG_OFFSET) < tcph->sum) { /* tcph->sum は TCP の SDU 長 */ 1204 1164 1205 1165 /* 1206 * ç·æ¥ãã¤ã³ã¿ã®ä½ç½®ããä»ååä¿¡ããã»ã°ã¡ã³ãå 1207 ã®å ´åã¯ã 1208 * ã³ã¼ã«ããã¯é¢æ°ãå¼ã³åºãã 1166 * 緊急ポインタの位置が、今回受信したセグメント内の場合は、 1167 * コールバック関数を呼び出す。 1209 1168 */ 1210 1169 cep->urg_tcph = tcph; … … 1229 1188 1230 1189 if (cep->urg_tcph != NULL) { 1231 /* ã³ã¼ã«ããã¯é¢æ°å 1232 㧠tcp_rcv_oob() ãå¼åºããªãã£ãã*/ 1190 /* コールバック関数内で tcp_rcv_oob() を呼出さなかった。*/ 1233 1191 cep->urg_tcph = NULL; 1234 1192 tcph->urp = 0; … … 1236 1194 else { 1237 1195 /* 1238 * ã³ã¼ã«ããã¯é¢æ°å 1239 㧠tcp_rcv_oob() ãå¼åºããæã¯ã 1240 * SDU é·ã®è£æ£å¤ãè¨å®ããã 1196 * コールバック関数内で tcp_rcv_oob() を呼出した時は、 1197 * SDU 長の補正値を設定する。 1241 1198 */ 1242 1199 tcph->urp = 1; … … 1265 1222 1266 1223 /* 1267 * drop_after_ack -- åä¿¡ã»ã°ã¡ã³ããç ´æ£ããå¾ãACK ãè¿ã (注æ: ååã¨ã¯åã£ã¦ããªã)ã1224 * drop_after_ack -- 受信セグメントを破棄した後、ACK を返す (注意: 名前とは合っていない)。 1268 1225 * 1269 * æ»ãå¤:1270 * RET_RETURN æ£å¸¸ããªã¿ã¼ã³ããã1271 * RET_RST_DROP ã¨ã©ã¼ãRST ãéä¿¡ããã»ã°ã¡ã³ããç ´æ£ããã1226 * 戻り値: 1227 * RET_RETURN 正常、リターンする。 1228 * RET_RST_DROP エラー、RST を送信し、セグメントを破棄する。 1272 1229 */ 1273 1230 … … 1278 1235 1279 1236 /* 1280 * SYN åä¿¡ç¶æ 1281 ã§ãACK ãéé確èªããã¦ããªãæå°éä¿¡ SEQ (snd_una) ãã 1282 * åã®å¤ããéä¿¡ãããæ大 SEQ (snd_max) ããå¾ã®å¤ã®å ´åã¯ãç¸æã« RST ã 1283 * éã£ã¦çµäºãããããã¯ã"LAND" DoS æ»æã¸ã®é²å¾¡ã§ãããå½é ããã SYN 1284 * ã»ã°ã¡ã³ããéä¿¡ãã¤ã¥ãããã¼ãéã§ã® ACK ã¹ãã¼ã ãé²ãã 1237 * SYN 受信状態で、ACK が送達確認されていない最小送信 SEQ (snd_una) より 1238 * 前の値か、送信された最大 SEQ (snd_max) より後の値の場合は、相手に RST を 1239 * 送って終了する。これは、"LAND" DoS 攻撃への防御であり、偽造された SYN 1240 * セグメントを送信しつづけるポート間での ACK ストームを防ぐ。 1285 1241 */ 1286 1242 if (cep->fsm_state == TCP_FSM_SYN_RECVD && (tcph->flags & TCP_FLG_ACK) && … … 1291 1247 syscall(rel_net_buf(input)); 1292 1248 1293 /* éä¿¡ãæ示ããã*/1249 /* 送信を指示する。*/ 1294 1250 cep->flags |= TCP_CEP_FLG_ACK_NOW | TCP_CEP_FLG_POST_OUTPUT; 1295 1251 sig_sem(SEM_TCP_POST_OUTPUT); … … 1298 1254 1299 1255 /* 1300 * close_connection -- ã³ãã¯ã·ã§ã³éæ¾å¦çãç¸æãã FIN ãåä¿¡ããã1256 * close_connection -- コネクション開放処理、相手から FIN を受信した。 1301 1257 */ 1302 1258 … … 1323 1279 1324 1280 switch (cep->fsm_state) { 1325 case TCP_FSM_SYN_RECVD: /* SYN ãåä¿¡ããSYN éä¿¡æ¸ã¿*/1326 case TCP_FSM_ESTABLISHED: /* ã³ãã¯ã·ã§ã³éè¨å®äº*/1281 case TCP_FSM_SYN_RECVD: /* SYN を受信し、SYN 送信済み */ 1282 case TCP_FSM_ESTABLISHED: /* コネクション開設完了 */ 1327 1283 cep->fsm_state = TCP_FSM_CLOSE_WAIT; 1328 1284 syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_RWBUF_READY)); 1329 1285 break; 1330 1286 1331 case TCP_FSM_FIN_WAIT_1: /* APP ãçµäºãFIN éä¿¡æ¸ã¿ãACK å¾ 1332 ã¡ */ 1287 case TCP_FSM_FIN_WAIT_1: /* APP が終了、FIN 送信済み、ACK 待ち */ 1333 1288 cep->fsm_state = TCP_FSM_CLOSING; 1334 1289 break; 1335 1290 1336 case TCP_FSM_FIN_WAIT_2: /* ç¸æããã® FIN å¾ 1337 ã¡ */ 1291 case TCP_FSM_FIN_WAIT_2: /* 相手からの FIN 待ち */ 1338 1292 cep->fsm_state = TCP_FSM_TIME_WAIT; 1339 1293 tcp_cancel_timers(cep); … … 1341 1295 1342 1296 /* 1343 * FIN WAIT 2 ç¶æ 1344 ã§ã¯ã 1345 * åä¿¡ã¯å¯è½ã§ãããããã§ã«éä¿¡ã¯çµäºãã¦ããã 1346 * ç¸æã®éä¿¡ãçµäºããã®ã§ãå 1347 ¥åã¿ã¹ã¯ã®ã¿èµ·åºããã 1297 * FIN WAIT 2 状態では、 1298 * 受信は可能であるが、すでに送信は終了している。 1299 * 相手の送信も終了したので、入力タスクのみ起床する。 1348 1300 */ 1349 1301 syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY)); … … 1351 1303 #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 1352 1304 1353 /* ç¸æããã® FIN ã«å¯¾ãã¦å¿çãè¿ãã*/1305 /* 相手からの FIN に対して応答を返す。*/ 1354 1306 tcp_respond(NULL, cep, cep->rcv_nxt, cep->snd_una, 1355 1307 cep->rbufsz - cep->rwbuf_count, TCP_FLG_ACK); … … 1358 1310 1359 1311 /* 1360 * å¿ 1361 è¦ãªæ 1362 å ±ã Time Wait ç¨ TCP é信端ç¹ã«ç§»ãã¦ã 1363 * æ¨æºã® TCP é信端ç¹ãéæ¾ããã 1312 * 必要な情報を Time Wait 用 TCP 通信端点に移して、 1313 * 標準の TCP 通信端点を開放する。 1364 1314 */ 1365 1315 tcp_move_twcep(cep); … … 1369 1319 break; 1370 1320 1371 case TCP_FSM_TIME_WAIT: /* ç¸æããã® FIN åä¿¡æ¸ã¿ãæéå¾ 1372 ã¡ */ 1321 case TCP_FSM_TIME_WAIT: /* 相手からの FIN 受信済み、時間待ち */ 1373 1322 cep->timer[TCP_TIM_2MSL] = 2 * TCP_TVAL_MSL; 1374 1323 break; … … 1377 1326 1378 1327 /* 1379 * tcp_input -- TCP ã®å 1380 ¥åé¢æ° 1328 * tcp_input -- TCP の入力関数 1381 1329 * 1382 * 注æ: input ã«ã¯ IF ããã㨠IP ããããå 1383 é ã«ããã 1330 * 注意: input には IF ヘッダと IP ヘッダが先頭にある。 1384 1331 */ 1385 1332 … … 1407 1354 NET_COUNT_MIB(tcp_stats.tcpInSegs, 1); 1408 1355 1409 /* ãããé·ããã§ãã¯ããã*/1356 /* ヘッダ長をチェックする。*/ 1410 1357 if (input->len < IF_IP_TCP_HDR_SIZE(input)) { 1411 1358 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_BAD_HEADERS], 1); … … 1415 1362 tcph = GET_TCP_HDR(input, *offp); 1416 1363 1417 seglen = input->len - *offp; /* TCP ã®ã»ã°ã¡ã³ãé·*/1364 seglen = input->len - *offp; /* TCP のセグメント長 */ 1418 1365 1419 1366 if (IN_CKSUM(input, IPPROTO_TCP, *offp, (uint_t)seglen) != 0) { … … 1422 1369 } 1423 1370 1424 /* TCP ãããé·ããã§ãã¯ããã*/1371 /* TCP ヘッダ長をチェックする。*/ 1425 1372 if (TCP_HDR_LEN(tcph->doff) < TCP_HDR_SIZE || TCP_HDR_LEN(tcph->doff) > seglen) { 1426 1373 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_BAD_HEADERS], 1); 1427 1374 goto drop; 1428 1375 } 1429 tcph->sum = seglen - TCP_HDR_LEN(tcph->doff); /* ãããã tcph->sum 㯠TCP ã® SDU é·*/1376 tcph->sum = seglen - TCP_HDR_LEN(tcph->doff); /* ここから tcph->sum は TCP の SDU 長 */ 1430 1377 1431 1378 /* 1432 * SYN 㨠FIN ã®ä¸¡ããããã»ããããã¦ããã°ç ´æ£ãããnmap çã®å¯¾ç1433 * ãã ããRFC1644 T/TCP æ¡å¼µæ©è½ã¨ç«¶åããã1379 * SYN と FIN の両ビットがセットされていれば破棄する。nmap 等の対策 1380 * ただし、RFC1644 T/TCP 拡張機能と競合する。 1434 1381 */ 1435 1382 if ((tcph->flags & (TCP_FLG_SYN | TCP_FLG_FIN)) == (TCP_FLG_SYN | TCP_FLG_FIN)) 1436 1383 goto drop; 1437 1384 1438 /* ãããã¯ã¼ã¯ãªã¼ãã¼ãããã¹ããªã¼ãã¼ã«å¤æããã*/1385 /* ネットワークオーダーからホストオーダーに変換する。*/ 1439 1386 1440 1387 NTOHL(tcph->seq); … … 1445 1392 NTOHS(tcph->dport); 1446 1393 1447 /* SDU é· ãã ç·æ¥ãã¤ã³ã¿ã大ããå ´å*/1394 /* SDU 長 より 緊急ポインタが大きい場合 */ 1448 1395 if (tcph->urp > tcph->sum) 1449 1396 goto drop; … … 1454 1401 1455 1402 /* 1456 * ç¶æ 1457 ã Time Wait ä¸ã® CEP ãæ¢ç´¢ããã 1403 * 状態が Time Wait 中の CEP を探索する。 1458 1404 */ 1459 1405 twcep = tcp_find_twcep(input, *offp); 1460 1406 if (twcep != NULL) { 1461 1407 1462 if (tcph->flags & TCP_FLG_RST) /* RST ãã©ã°ãåä¿¡ããã¨ãã¯ç¡è¦ããã*/1408 if (tcph->flags & TCP_FLG_RST) /* RST フラグを受信したときは無視する。*/ 1463 1409 goto drop; 1464 1410 else { 1465 1411 1466 1412 /* 1467 * TCP é信端ç¹ã Time Wait ã®æãç¸æãã¹ãããã»ã°ã¡ã³ããæ¥ãã¨ãã¯ã1468 * ç¸æãã¹ãã® FIN ã«å¯¾ããèªãã¹ãã® ACK ã»ã°ã¡ã³ããéä¸ã§1469 * æ失ãããã¨ãæå³ãã¦ããã®ã§ãACK ã»ã°ã¡ã³ããåéããã1413 * TCP 通信端点が Time Wait の時、相手ホストからセグメントが来たときは、 1414 * 相手ホストの FIN に対する自ホストの ACK セグメントが途中で 1415 * 損失したことを意味しているので、ACK セグメントを再送する。 1470 1416 */ 1471 1417 1472 /* ãã¹ããªã¼ãã¼ãããããã¯ã¼ã¯ãªã¼ãã¼ã«æ»ãã*/1418 /* ホストオーダーからネットワークオーダーに戻す。*/ 1473 1419 HTONS(tcph->sport); 1474 1420 HTONS(tcph->dport); … … 1479 1425 } 1480 1426 else 1481 /* æ¨æºã® TCP é信端ç¹ãå¾ãã*/1427 /* 標準の TCP 通信端点を得る。*/ 1482 1428 cep = tcp_find_cep(input, *offp); 1483 1429 1484 1430 #else /* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */ 1485 1431 1486 /* TCP é信端ç¹ãå¾ãã*/1432 /* TCP 通信端点を得る。*/ 1487 1433 cep = tcp_find_cep(input, *offp); 1488 1434 … … 1490 1436 1491 1437 /* 1492 * TCP é信端ç¹ããªãå ´å㨠CEP ã®ç¶æ 1493 ãã¯ãã¼ãºãªãç ´æ£ããã 1438 * TCP 通信端点がない場合と CEP の状態がクローズなら破棄する。 1494 1439 */ 1495 1440 if (cep == NULL) { … … 1509 1454 1510 1455 /* 1511 * ã³ãã¯ã·ã§ã³éè¨æ¸ã¿ã§ã»ã°ã¡ã³ããåä¿¡ããã¨ãã¯ã1512 * ã¢ã¤ãã«æéã¨çå確èªã¿ã¤ãããªã»ããããã1456 * コネクション開設済みでセグメントを受信したときは、 1457 * アイドル時間と生存確認タイマをリセットする。 1513 1458 */ 1514 1459 cep->idle = 0; … … 1517 1462 } 1518 1463 1519 /* CEP ã®ç¶æ 1520 ã LISTEN 以å¤ã®æã¯ããªãã·ã§ã³ãå¦çããã*/ 1464 /* CEP の状態が LISTEN 以外の時は、オプションを処理する。*/ 1521 1465 if (cep->fsm_state != TCP_FSM_LISTEN) 1522 1466 parse_option(tcph, cep); 1523 1467 1524 1468 /* 1525 * åä¿¡å¯è½ã¦ã£ã³ããµã¤ãºãè¨ç®ããã1469 * 受信可能ウィンドサイズを計算する。 1526 1470 * 1527 * rcv_nxt: åä¿¡ãæå¾ 1528 ãã¦ããæå°ã® SEQï¼ãã以åã¯åä¿¡æ¸ã¿ï¼ 1529 * rcv_adv: åä¿¡ãæå¾ 1530 ãã¦ããæ大㮠SEQ 1531 * rbufsz: åä¿¡ã¦ã£ã³ããããã¡ãµã¤ãº 1532 * rwbuf_count: åä¿¡ã¦ã£ã³ããããã¡ã«ãããã¼ã¿é 1533 * tcph->sum: ä»ååä¿¡ãã SDU ãµã¤ãº 1471 * rcv_nxt: 受信を期待している最小の SEQ(これ以前は受信済み) 1472 * rcv_adv: 受信を期待している最大の SEQ 1473 * rbufsz: 受信ウィンドバッファサイズ 1474 * rwbuf_count: 受信ウィンドバッファにあるデータ量 1475 * tcph->sum: 今回受信した SDU サイズ 1534 1476 * 1535 * ä»ååä¿¡ããã»ã°ã¡ã³ããé åºæ´åãã¥ã¼ã«é£çµãã 1536 * å¯è½æ§ãããã®ã§ tcph->sum ãèæ 1537 ®ããã 1477 * 今回受信したセグメントを順序整列キューに連結する 1478 * 可能性があるので tcph->sum を考慮する。 1538 1479 * 1539 1480 */ … … 1546 1487 cep->rcv_wnd = cep->rcv_adv - cep->rcv_nxt; 1547 1488 1548 /* CEP ã®ç¶æ 1549 ã«ããå¦çãè¡ãã*/ 1550 1551 if (cep->fsm_state == TCP_FSM_LISTEN) { /* ååãªã¼ãã³ (LISTEN) ã®å¦çã*/ 1489 /* CEP の状態により処理を行う。*/ 1490 1491 if (cep->fsm_state == TCP_FSM_LISTEN) { /* 受動オープン (LISTEN) の処理。*/ 1552 1492 if ((ret = listening(input, cep, *offp, iss)) == RET_RST_DROP) 1553 1493 goto reset_drop; 1554 1494 else if (ret == RET_DROP) 1555 1495 goto drop; 1556 trim_length(tcph, cep); /* åä¿¡ãã SDU é·ã調æ´ããã*/1557 1558 if (tcph->flags & TCP_FLG_ACK) { /* ACK ãã©ã°ã®å¦ç*/1496 trim_length(tcph, cep); /* 受信した SDU 長を調整する。*/ 1497 1498 if (tcph->flags & TCP_FLG_ACK) { /* ACK フラグの処理 */ 1559 1499 if ((ret = proc_ack2(input, cep, *offp, &needoutput)) == RET_DROP) 1560 1500 goto drop; … … 1565 1505 } 1566 1506 } 1567 else if (cep->fsm_state == TCP_FSM_SYN_SENT) { /* è½åãªã¼ãã³ãSYN éä¿¡æ¸ã¿*/1507 else if (cep->fsm_state == TCP_FSM_SYN_SENT) { /* 能動オープン、SYN 送信済み */ 1568 1508 if ((ret = syn_sent(tcph, cep)) == RET_RST_DROP) 1569 1509 goto reset_drop; 1570 1510 else if (ret == RET_DROP) 1571 1511 goto drop; 1572 trim_length(tcph, cep); /* åä¿¡ãã SDU é·ã調æ´ããã*/1573 1574 if (tcph->flags & TCP_FLG_ACK) { /* ACK ãã©ã°ã®å¦ç*/1512 trim_length(tcph, cep); /* 受信した SDU 長を調整する。*/ 1513 1514 if (tcph->flags & TCP_FLG_ACK) { /* ACK フラグの処理 */ 1575 1515 if ((ret = proc_ack2(input, cep, *offp, &needoutput)) == RET_DROP) 1576 1516 goto drop; … … 1582 1522 } 1583 1523 else { 1584 if (cep->fsm_state == TCP_FSM_SYN_RECVD) { /* SYN ãåä¿¡ãSYN éä¿¡æ¸ã¿*/1524 if (cep->fsm_state == TCP_FSM_SYN_RECVD) { /* SYN を受信、SYN 送信済み */ 1585 1525 /* 1586 * ç¸æããå信確èªãéããã¦æ¥ã¦ãã1526 * 相手から受信確認が送られて来ても、 1587 1527 * 1588 * ACK <= æªç¢ºèªã®æå°éä¿¡SEQ (snd_una) &&1589 * éä¿¡ããæ大SEQ (snd_max) < ACK1528 * ACK <= 未確認の最小送信 SEQ (snd_una) && 1529 * 送信した最大 SEQ (snd_max) < ACK 1590 1530 * 1591 * ãªãããªã»ãããéã£ã¦ã»ã°ã¡ã³ããç ´æ£ããã1531 * なら、リセットを送ってセグメントを破棄する。 1592 1532 */ 1593 1533 if ((tcph->flags & TCP_FLG_ACK) && … … 1598 1538 1599 1539 /* 1600 * RST ãã©ã°ãåä¿¡ããã¨ãã®å¦ç (ç°å¸¸åæ)1540 * RST フラグを受信したときの処理 (異常切断) 1601 1541 */ 1602 1542 if (tcph->flags & TCP_FLG_RST) { … … 1604 1544 SEQ_LT(tcph->seq, cep->last_ack_sent + cep->rcv_wnd)) { 1605 1545 /* 1606 * åä¿¡ããã»ã°ã¡ã³ãã® SEQ ããæå¾ã«éä¿¡ããACK (last_ack_sent)1607 * ãããåä¿¡ã¦ã¤ã³ãã¦ãµã¤ãºã¾ã§ã®éã®å¦ç1546 * 受信したセグメントの SEQ が、最後に送信した ACK (last_ack_sent) 1547 * から、受信ウインドウサイズまでの間の処理 1608 1548 */ 1609 1549 switch (cep->fsm_state) { 1610 case TCP_FSM_SYN_RECVD: /* SYN ãåä¿¡ããSYN éä¿¡æ¸ã¿*/1611 1612 cep->net_error = EV_CNNRF; /* æ¥ç¶ä¸è½*/1550 case TCP_FSM_SYN_RECVD: /* SYN を受信し、SYN 送信済み */ 1551 1552 cep->net_error = EV_CNNRF; /* 接続不能 */ 1613 1553 cep->error = E_CLS; 1614 1554 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_RSTS], 1); … … 1617 1557 break; 1618 1558 1619 case TCP_FSM_ESTABLISHED: /* ã³ãã¯ã·ã§ã³éè¨å®äº */ 1620 case TCP_FSM_CLOSE_WAIT: /* FIN åä¿¡ãã¯ãã¼ãºå¾ 1621 ã¡ */ 1559 case TCP_FSM_ESTABLISHED: /* コネクション開設完了 */ 1560 case TCP_FSM_CLOSE_WAIT: /* FIN 受信、クローズ待ち */ 1622 1561 NET_COUNT_MIB(tcp_stats.tcpEstabResets, 1); 1623 1562 /* fallthrough */ 1624 1563 1625 case TCP_FSM_FIN_WAIT_1: /* çµäºãã¦ãFIN éä¿¡æ¸ã¿ */ 1626 case TCP_FSM_FIN_WAIT_2: /* çµäºãFIN ä¼é確èªåä¿¡ãFINå¾ 1627 ã¡ */ 1628 1629 cep->net_error = EV_CNRST; /* æ¥ç¶ãªã»ãã */ 1564 case TCP_FSM_FIN_WAIT_1: /* 終了して、FIN 送信済み */ 1565 case TCP_FSM_FIN_WAIT_2: /* 終了、FIN 伝達確認受信、FIN待ち */ 1566 1567 cep->net_error = EV_CNRST; /* 接続リセット */ 1630 1568 cep->error = E_CLS; 1631 1569 NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_RSTS], 1); 1632 1570 /* no break; */ 1633 1571 1634 case TCP_FSM_CLOSING: /* çµäºãFIN 交ææ¸ã¿ãACK å¾ 1635 ã¡ */ 1636 case TCP_FSM_LAST_ACK: /* FIN åä¿¡ãçµäºãACK å¾ 1637 ã¡ */ 1572 case TCP_FSM_CLOSING: /* 終了、FIN 交換済み、ACK 待ち */ 1573 case TCP_FSM_LAST_ACK: /* FIN 受信、終了、ACK 待ち */ 1638 1574 1639 1575 cep = tcp_close(cep); … … 1645 1581 1646 1582 /* 1647 * CEP ã®ç¶æ 1648 ã SYN ãåä¿¡ããSYN éä¿¡æ¸ã¿ã®å ´åã¯ã 1649 * åä¿¡ã¦ã£ã³ãã«åã¾ãããã«ãã¼ã¿ã 1650 * 調æ´ããåã«ããã®æ¥ç¶ã«ãããã±ãããã©ãããæ¤è¨¼ããã 1583 * CEP の状態が SYN を受信し、SYN 送信済みの場合は、 1584 * 受信ウィンドに収まるようにデータを 1585 * 調整する前に、この接続によるパケットかどうかを検証する。 1651 1586 * 1652 * åä¿¡ããç¸æã® SEQ < ç¸æã® SEQ ã®åæå¤(irs)1587 * 受信した相手の SEQ < 相手の SEQ の初期値 (irs) 1653 1588 * 1654 * ããã¯ã"LAND" DoS æ»æã®é²å¾¡ã§ããã1589 * これは、"LAND" DoS 攻撃の防御である。 1655 1590 */ 1656 1591 if (cep->fsm_state == TCP_FSM_SYN_RECVD && SEQ_LT(tcph->seq, cep->irs)) { … … 1659 1594 1660 1595 /* 1661 * åä¿¡ãæå¾ 1662 ãã¦ããæå°ã® SEQ (rcv_nxt) - åä¿¡ããç¸æã® SEQ ã 1663 * æ£ãªããrcv_nxt 以åã®ãã¼ã¿ã¯ãã§ã«åä¿¡ãã¦ããã®ã§ããã®é¨åã 1664 * åé¤ããã 1596 * 受信を期待している最小の SEQ (rcv_nxt) - 受信した相手の SEQ が 1597 * 正なら、rcv_nxt 以前のデータはすでに受信しているので、その部分を 1598 * 削除する。 1665 1599 * <---------- rcv_wnd ---------> 1666 1600 * rcv_nxt rcv_nxt + rcv_wnd … … 1674 1608 * ^ ^ 1675 1609 * seq seq + len 1676 * <---------------> åé¤ããã1610 * <---------------> 削除する。 1677 1611 */ 1678 1612 todrop = cep->rcv_nxt - tcph->seq; … … 1680 1614 1681 1615 /* 1682 * SYN ãã©ã°ãã¤ãã¦ããã¨ãã¯ããã®å (1 ãªã¯ããã)1683 * SEQ ãé²ããç·æ¥ãã¤ã³ã¿ã¨åé¤ããé·ãã調æ´ããã1616 * SYN フラグがついているときは、その分 (1 オクテット) 1617 * SEQ を進め、緊急ポインタと削除する長さを調整する。 1684 1618 */ 1685 1619 if (tcph->flags & TCP_FLG_SYN) { … … 1694 1628 1695 1629 /* 1696 * åé¤ããé·ãã SDU ããé·ããã¤ã¾ããåä¿¡ãæå¾ 1697 ãã¦ãã 1698 * æå°ã® SEQ (rcv_nxt) ã«éãã¦ããªããã 1699 * åé¤ããé·ãã SDU ã¨åãã§ãFIN ãã©ã°ãã¤ãã¦ãªããã° 1700 * å 1701 ¨ã¦åé¤ããã 1630 * 削除する長さが SDU より長い、つまり、受信を期待している 1631 * 最小の SEQ (rcv_nxt) に達していないか、 1632 * 削除する長さが SDU と同じで、FIN フラグがついてなければ 1633 * 全て削除する。 1702 1634 */ 1703 if ( todrop > tcph->sum || /* tcph->sum 㯠TCP ã® SDU é·*/1635 if ( todrop > tcph->sum || /* tcph->sum は TCP の SDU 長 */ 1704 1636 (todrop == tcph->sum && (tcph->flags & TCP_FLG_FIN) == 0)) { 1705 1637 tcph->flags &= ~TCP_FLG_FIN; 1706 1638 cep->flags |= TCP_CEP_FLG_ACK_NOW; 1707 todrop = tcph->sum; /* tcph->sum 㯠TCP ã® SDU é·*/1639 todrop = tcph->sum; /* tcph->sum は TCP の SDU 長 */ 1708 1640 } 1709 1641 1710 1642 /* 1711 * SDU ãåã«è©°ããã1643 * SDU を前に詰める。 1712 1644 */ 1713 if (todrop < tcph->sum) { /* tcph->sum 㯠TCP ã® SDU é·*/1645 if (todrop < tcph->sum) { /* tcph->sum は TCP の SDU 長 */ 1714 1646 memcpy(GET_TCP_SDU(input, *offp), 1715 1647 GET_TCP_SDU(input, *offp) + todrop, (size_t)(tcph->sum - todrop)); … … 1717 1649 1718 1650 /* 1719 * SEQ 㨠SDU é·ã調æ´ããã1651 * SEQ と SDU 長を調整する。 1720 1652 */ 1721 1653 tcph->seq += todrop; 1722 tcph->sum -= (uint16_t)todrop; /* tcph->sum 㯠TCP ã® SDU é·*/1654 tcph->sum -= (uint16_t)todrop; /* tcph->sum は TCP の SDU 長 */ 1723 1655 1724 1656 /* 1725 * ç·æ¥ãã¤ã³ã¿ã調æ´ããã1657 * 緊急ポインタを調整する。 1726 1658 */ 1727 1659 if (tcph->urp > todrop) … … 1736 1668 1737 1669 /* 1738 * ããã¦ã¼ã¶ã¿ã¹ã¯ãçµäºããå¾ã«ããã¼ã¿ãåä¿¡ãã1739 * å ´åã¯ãRST ãéãã1740 */ 1741 if (cep->fsm_state == TCP_FSM_LAST_ACK && tcph->sum > 0) { /* tcph->sum 㯠TCP ã® SDU é·*/1670 * もしユーザタスクが終了した後に、データを受信した 1671 * 場合は、RST を送る。 1672 */ 1673 if (cep->fsm_state == TCP_FSM_LAST_ACK && tcph->sum > 0) { /* tcph->sum は TCP の SDU 長 */ 1742 1674 cep = tcp_close(cep); 1743 1675 goto reset_drop; … … 1745 1677 1746 1678 /* 1747 * åä¿¡ã»ã°ã¡ã³ããåä¿¡ã¦ã£ã³ããè¶ 1748 ããå ´åã¯ã 1749 * è¶ 1750 ããåãåãã 1679 * 受信セグメントが受信ウィンドを超える場合は、 1680 * 超えた分を削る。 1751 1681 * 1752 1682 * <---------- rcv_wnd ---------> … … 1761 1691 * ^ ^ 1762 1692 * seq seq + len 1763 * <-----> åé¤ããã1764 */ 1765 todrop = (tcph->seq + tcph->sum) - (cep->rcv_nxt + cep->rcv_wnd); /* tcph->sum 㯠TCP ã® SDU é·*/1693 * <-----> 削除する。 1694 */ 1695 todrop = (tcph->seq + tcph->sum) - (cep->rcv_nxt + cep->rcv_wnd); /* tcph->sum は TCP の SDU 長 */ 1766 1696 if (todrop > 0) { 1767 if (todrop > tcph->sum) { /* tcph->sum 㯠TCP ã® SDU é·*/1697 if (todrop > tcph->sum) { /* tcph->sum は TCP の SDU 長 */ 1768 1698 /* 1769 * åä¿¡ãã SDU ã®å 1770 ¨ã¦ãåä¿¡ã¦ã£ã³ããè¶ 1771 ããå ´åã 1699 * 受信した SDU の全てが受信ウィンドを超える場合。 1772 1700 * 1773 * TIME_WAIT ä¸ã«ãæ°ããªæ¥ç¶è¦æ±ãåä¿¡ããã1774 * å¤ãæ¥ç¶ãç ´æ£ããæ°ããªæ¥ç¶ãéå§ããã1775 * ãã ããSEQ ã¯åããé²ãã§ããªããã°ãªããªãã1701 * TIME_WAIT 中に、新たな接続要求を受信したら 1702 * 古い接続を破棄し、新たな接続を開始する。 1703 * ただし、SEQ は前より進んでいなければならない。 1776 1704 */ 1777 1705 if ((tcph->flags & TCP_FLG_SYN) && … … 1785 1713 1786 1714 /* 1787 * åä¿¡ã¦ã£ã³ãã 0 ã§ãåä¿¡ãã SEQ 㨠1788 * åä¿¡ãæå¾ 1789 ãã¦ããæå°ã® SEQ ãä¸è´ããã¨ã㯠1790 * ACK ãè¿ãããã以å¤ã¯ãã¼ã¿ãç ´æ£ããACK ãè¿ãã 1715 * 受信ウィンドが 0 で、受信した SEQ と 1716 * 受信を期待している最小の SEQ が一致したときは 1717 * ACK を返す。それ以外はデータを破棄し、ACK を返す。 1791 1718 */ 1792 1719 if (cep->rcv_wnd == 0 && (tcph->seq == cep->rcv_nxt || tcph->sum == 0)) { … … 1799 1726 } 1800 1727 } 1801 tcph->sum -= (uint16_t)todrop; /* tcph->sum 㯠TCP ã® SDU é·*/1728 tcph->sum -= (uint16_t)todrop; /* tcph->sum は TCP の SDU 長 */ 1802 1729 tcph->flags &= ~(TCP_FLG_PUSH | TCP_FLG_FIN); 1803 1730 } 1804 1731 1805 1732 /* 1806 * ãããSYN ãã»ããããã¦ããã°ã1807 * ã¨ã©ã¼ãªã®ã§ RST ãéããæ¥ç¶ãç ´æ£ããã1733 * もし、SYN がセットされていれば、 1734 * エラーなので RST を送り、接続を破棄する。 1808 1735 */ 1809 1736 if (tcph->flags & TCP_FLG_SYN) { … … 1814 1741 1815 1742 /* 1816 * ãããACK ãã»ããããã¦ããªãå ´åã¯ã 1817 * ç¶æ 1818 ã SYN åä¿¡æ¸ã¿ã 1819 * SYN ãéä¿¡ãããã¨ãã¦ããã°ãå¦çãç¶ãããã 1820 * ãã以å¤ã¯ã»ã°ã¡ã³ããç ´æ£ãã¦çµäºããã 1743 * もし、ACK がセットされていない場合は、 1744 * 状態が SYN 受信済みか 1745 * SYN を送信しようとしていれば、処理を続けるが、 1746 * それ以外はセグメントを破棄して終了する。 1821 1747 */ 1822 1748 if ((tcph->flags & TCP_FLG_ACK) == 0) { … … 1826 1752 else { 1827 1753 /* 1828 * ACK ã®å¦ç1754 * ACK の処理 1829 1755 */ 1830 1756 ret = proc_ack1(input, cep, *offp, &needoutput); … … 1840 1766 /* step 6 */ 1841 1767 1842 /* éä¿¡ã¦ã£ã³ããæ´æ°ããã*/1768 /* 送信ウィンドを更新する。*/ 1843 1769 if (update_wnd(tcph, cep) == true) 1844 1770 needoutput = true; 1845 1771 1846 /* ç·æ¥ãã¼ã¿ãå¦çããã*/1772 /* 緊急データを処理する。*/ 1847 1773 proc_urg(tcph, cep); 1848 1774 … … 1850 1776 1851 1777 /* 1852 * SDU ãããããFIN ãæªåä¿¡ã®ç¶æ 1853 ã§ãæåã« FIN ãåä¿¡ããã¨ãã 1854 * åä¿¡ã»ã°ã¡ã³ããã¥ã¼ã« net_buf ã追å ããã 1855 * ãã以å¤ã®å ´åã¯ãã»ã°ã¡ã³ããç ´æ£ããã 1778 * SDU があるか、FIN を未受信の状態で、最初に FIN を受信したとき、 1779 * 受信セグメントキューに net_buf を追加する。 1780 * それ以外の場合は、セグメントを破棄する。 1856 1781 */ 1857 1782 flags = tcph->flags; 1858 if ((tcph->sum > 0 || (flags & TCP_FLG_FIN)) && /* tcph->sum 㯠TCP ã® SDU é·*/1783 if ((tcph->sum > 0 || (flags & TCP_FLG_FIN)) && /* tcph->sum は TCP の SDU 長 */ 1859 1784 TCP_FSM_HAVE_RCVD_FIN(cep->fsm_state) == 0) { 1860 1785 flags = reassemble(input, cep, *offp, flags); … … 1866 1791 1867 1792 /* 1868 * FIN ãåä¿¡ãããã³ãã¯ã·ã§ã³ãã¯ãã¼ãºããã1793 * FIN を受信したらコネクションをクローズする。 1869 1794 */ 1870 1795 if (flags & TCP_FLG_FIN) 1871 1796 close_connection(cep, &needoutput); 1872 1797 1873 /* åºåãè¡ã£ãå¾çµäºããã*/1798 /* 出力を行った後終了する。*/ 1874 1799 if (needoutput == true || (cep->flags & TCP_CEP_FLG_ACK_NOW)) { 1875 /* éä¿¡ãæ示ããã*/1800 /* 送信を指示する。*/ 1876 1801 cep->flags |= TCP_CEP_FLG_POST_OUTPUT; 1877 1802 sig_sem(SEM_TCP_POST_OUTPUT); … … 1882 1807 reset_drop: 1883 1808 /* 1884 * RST éä¿¡å¦ç1809 * RST 送信処理 1885 1810 */ 1886 1811 … … 1888 1813 goto drop; 1889 1814 1890 /* ãã¹ããªã¼ãã¼ãããããã¯ã¼ã¯ãªã¼ãã¼ã«æ»ãã*/1815 /* ホストオーダーからネットワークオーダーに戻す。*/ 1891 1816 1892 1817 HTONS(tcph->sport); … … 1902 1827 else { 1903 1828 if (tcph->flags & TCP_FLG_SYN) 1904 tcph->sum ++; /* tcph->sum 㯠SDU é·*/1829 tcph->sum ++; /* tcph->sum は SDU 長 */ 1905 1830 tcp_respond(input, cep, tcph->seq + tcph->sum, 0, rbfree, TCP_FLG_RST | TCP_FLG_ACK); 1906 1831 } 1907 1832 1908 /* input 㯠tcp_respoond ã§è¿å´ãããã*/1833 /* input は tcp_respoond で返却される。*/ 1909 1834 NET_COUNT_TCP(net_count_tcp[NC_TCP_SEND_RSTS], 1); 1910 1835 NET_COUNT_MIB(tcp_stats.tcpOutRsts, 1);
Note:
See TracChangeset
for help on using the changeset viewer.