Download presentation
Presentation is loading. Please wait.
Published byClaribel Mills Modified over 9 years ago
1
Chapter 26. TCP Output 안 진 섭 jinsurby@hufs.ac.kr TCP/IP Illustrated Vol.2
2
Page 2 Contents 26.1 Introduction 26.2 tcp_output Overview 26.3 Determine if a segment should be sent 26.4 TCP options 26.5 Window Scale Option 26.6 Timestamp Option 26.7 Save a Segment 26.8 tcp_template Function 26.9 tcp_respond Function
3
Page 3 26.1 Introduction The tcp_output() is called whenever a segment needs to be sent on a connection. tcp_usrreq() PRU_CONNECT (initial SYN), PRU_SHUTDOWN(FIN), PRU_SEND(send data), PRU_SENDOOB(out-of-band data) tcp_fasttimo() : delayed ACK tcp_timers() Segment 재전송 (Retransmission timer expires) Persist probe 전송 (persist timer expires) tcp_drop() : RST tcp_disconnect : FIN tcp_input() immediate ACK 전송 Third consecutive duplicated ACK is received(to send a single segment, ‘the fast retransmission’)
4
Page 4 26.2 tcp_output Overview (1/2) Figure 26.1. tcp_output function: overview Go back slow start // idle : snd_max == snd_una ( 상대측 TCP 로 부터 ACK 를 받을 필요가 없는 상태 ) // idle 상태이고, one RTO 동안 segment 를 수신하지 못했다면 // congestion 이 발생한것으로 판단하고, slow start
5
Page 5 26.2 tcp_output Overview (2/2) Figure 26.1. tcp_output function: overview // sendalot : 하나 이상의 보낼 segment 가 남아있다면 ‘ 1 ’ 로 set
6
Page 6 26.3 determine if a segment should be sent (1/10) tcp_output() 은 segment 를 전송할 때 뿐만 아니라 socket receive buffer 의 data 를 process 에게 전달할 때도 호출됨 (PRU_RCVD request) Figure 26.2. tcp_output function: data is being forced out // send window 와 congestion window 중 작은값 선택 // persist timer expired 와 OOB senting 일 때만 ‘ 1 ’ // persist 상태 // send buffer 에 더 보내야할 data 가 있다면 FIN flag set 취소 // OOB data is sending
7
Page 7 26.3 determine if a segment should be sent (2/10) Figure 26.3. tcp_output function: calculate how much data to send // calculate amount of data to send (send buffer 와 window 둘중 작은값 ) // persist 상태 // send buffer 상의 가용공간 // 이번 segment 전송으로 send buffer 가 비는가 ? // 보내야할 data 가 maxseg 크기를 초과하면 len = maxseg // maxseg 만큼 보내고도 더 보내야할 data 가 있으므로 sendalot = 1
8
Page 8 26.3 determine if a segment should be sent (3/10)
9
Page 9 26.3 determine if a segment should be sent (4/10) Figure 26.8. tcp_output function: sender silly window avoidance // len = maxseg // idle 이거나 ( NODELAY 가 set 되어있고, 보내야할 data 가 send buffer 이상이라면 … ) // If the receiver ’ s window is at least half open // snd_max : 보냈던 highest seq no. (snd_max > snd_nxt, 재전송의 경우 )
10
Page 10 26.3 determine if a segment should be sent (5/10) Figure 26.9. tcp_output function: check if a window update should be sent // adv : 윈도우를 증가시킬 수 있는 량 // 2 full-sized segments // 가용 window 크기의 50% 이상이면 window update
11
Page 11 26.3 determine if a segment should be sent (6/10) TF_ACKNOW 가 설정되는 경우 200ms delayed ACK timer expires Segment is received out of order(for the fast retransmit algorithm) SYN is received during the three-way handshake Persist probe is received FIN received Figure 26.11. tcp_output function: should a segment should be sent? // TF_ACKNOW 가 설정됨 // urgend pointer is set by PRU_SENDOOB // segment 에 SYN or RST 가 설정됨 // segmnet 에 FIN flag 가 설정되어있고, 이전에 FIN 을 보냈다면 ( FIN 재전송 )
12
Page 12 26.3 determine if a segment should be sent (7/10) Figure 26.12. tcp_output function: enter persist state // send buffer 에 보내야할 data 가 있고 // retx timer 와 persist timer 가 설정되어있지 않다면 // persist timer 설정 (the other end 가 full-sized segment 를 수신할 만큼 buffer 에 여유가 없다는 상황을 의미 )
13
Page 13 26.3 determine if a segment should be sent (8/10) Example 가정 Process 는 idle connection 에서 100, 50byte 를 순서대로 write segment size 는 512bytes, receive window 는 4096 bytes 동작절차 첫 100 bytes 를 전송 Process 가 두번째 50 bytes write 할 때는 바로 전송하지 않음 50 bytes 는 full-sized segment 가 아님 Nagle algorithm 이 enable 되어있다면 TCP 는 이전 100 bytes 에 대한 ACK 대기중이기 때문 ( ‘t_force =0’ 을 의미 ) Receive window 가 4096 bytes 라고 한다면 50 bytes 는 2046 byte 보다 크지 않음 이전 100bytes 에 대한 ACK 를 수신할 때 까지 50 bytes 는 send buffer 에 있게됨
14
Page 14 26.3 determine if a segment should be sent (9/10) Example 1 (demonstrates the ACK-every-other-segment property of TCP) 가정 Segment size = 1024 bytes, receive buffer size = 4096 bytes There is no data to send. (TCP is just receiving) Receive buffer is empty
15
Page 15 26.3 determine if a segment should be sent (10/10) ① 상대측 TCP 가 1~1024 byte 전송 ② delayed ACK flag set rcv_nxt 이동 (by tcp_input) ③ PRU_RCVD request tcp_output the process reads the 1024 bytes. (Fig. 26.9) 4096 ④ window size 가 2 segments( 이 예제의 경우 2048byte) 를 초과할 때 까지 아무것도 전송 안함. ⑤ 단, delayed ACK flag 는 set 되므로 200ms 이후 timer 가 만료되면 ACK 전송 ⑥ next segment(1025~2048) 를 수신 tcp_input ⑦ tcp_output() the process reads bytes 1025-2048 ⑧ adv 값이 2 segments 이상이므로 ACK 전송 Example 2
16
Page 16 26.4 TCP Options (1/2) MSS, Window scale, timestamp option 을 TLV 형식으로 정의 // RFC 1323 // padding 과 유사 // len : total length
17
Page 17 26.4 TCP Options (2/2) TCP 는 window scale, timestamp option 의 interoperability 를 위해 다음 규칙을 적용 active open 단계 (=SYN) 에서 option 을 전송할 수 있다. 각 option 은 other end 가 해당 option 을 정의할 경우에만 enable 됨 TCP 는 passive open 단계 (=SYN, ACK) 에서 option 을 enable 하기위해 해당 option 을 정의해서 전송 (Figure 26.23) RFC 1323 을 지원하지 않을경우 window scale, timestamp option 은 무시
18
Page 18 26.5 Window Scale Option TCP header 의 16-bit window size field 제한을 없애기 위함 (long fat pipe 지원 ) SYN segment(SYN, SYN/ACK) 에서만 사용 (connection 이 종료될 때까지 계속 유지 ) // 0 : no scaling // 1~14 : shift counter 65535 * 2 14 = 1,073,725,440 bytes
19
Page 19 26.6 Timestamp Option (1/4) Sender 가 timestamp 를 전송한 후 receiver 의 timestamp reply 를 통해 RTT 를 계산 Sender 의 timestamp 상대방의 Timestamp (Tcb 내의 변수 ) Kernel 이 초기화시 0 으로 설정 매 500ms 마다 1 증가 ts_recent 를 copy 할 때 같이 copy Next expected seq. no (unless ACKs are delayed) AB tsvaltsecr tsvaltsecr tsvaltsecr
20
Page 20 26.6 Timestamp Option (2/4) Which Timestamp to Echo, RFC 1323 Algorithm 상대방의 Timestamp (Tcb 내의 변수 ) ts_recent 를 copy 할 때 같이 copy
21
Page 21 26.6 Timestamp Option (3/4) Which Timestamp to Echo, Corrected Algorithm Net/3 에서는 left edge of the window 의 이동에 상관없이 ts_val >= ts_recent (new timestamp, previous timestamp) 수신한 segment 의 시작 seq. no > the left edge of the window 만 확인
22
Page 22 26.6 Timestamp Option (4/4) Timestamps and Delayed ACKs // ti_seq (4) <= last_ack_sent(4) // ti_seq (6) <= last_ack_sent(4) O X
23
Page 23 26.7 Send a Segment (1/10) SYN segment 에서 MSS, window scale option 처리 Figure 26.23. tcp_output function: send options with first SYN segment TCP option 은 ‘ opt ’ array 에 저장 // SYN segment 에서 MSS option 은 항상 전송 됨 // MSS option 의 kind value // MSS option 의 length value // MSS option 의 MSS value Build MSS option Should window scale option be sent ? Build window scale option // TCPOPT_WINDOW : 3 // tcb 에 window scale option 이 setting 되었거나 window scale option 이 설정된 segment 를 받았다 면
24
Page 24 26.7 Send a Segment (2/10) Figure 26.24. tcp_output function: finish sending options Should timestamp option be sent ? Build timestamp option Check if options have overflowed segment Timestamp option 을 전송할 수 있는 조건 - TCP 가 timestamp option 을 요청할 수 있도록 설정됨 - RST flag 포함 안함 - Active open 단계 // TCPOPT_TSTAMP_HDR : 0x0101080a (NOP,NOP, TS) // tsval // tsecr // data length 가 MSS-optlen 보다 크다면 data length 는 감소되고 sendalot 을 1 로 set // optlen : option 의 길이
25
Page 25 26.7 Send a Segment (3/10) Figure 26.25. tcp_output function: update statistics, allocate mbuf for IP and TCP headers Update statistics // len : data length // t_force 가 1 이면서 data length == 1 : window probe // snd_nxt < snd_max : retransmission ( 한번에 보내므로 ) // normal data transmission Allocate an mbuf for IP and TCP headers Copy data into mbuf Set PSH flag // 100 – 40 – 16 (TCP option 이 없다고 가정 ) = 44 byte 이하 // 하나의 mbuf 에 data copy // 하나의 mbuf 에 data copy 가 안될경우 mbuf chain 생성 // segment length 와 send buffer 상의 data 크기가 같을경우 PSH flag set
26
Page 26 26.7 Send a Segment (4/10) Figure 26.26. tcp_output function: update statistics and allocate mbuf for IP and TCP headers Update statistics Get mbuf for IP and TCP headers // ACK only segment // control segment (SYN, FIN, RST) // urgent pointer 가 있는 segment // 위에 3 가지 경우가 아닐 때 window update // mbuf allocate // TCP template 가 없다면 … (Ch 26.8 에서 설명 ) // TCP template 가 있다면 내용을 copy Copy IP and TCP header templates into mbuf
27
Page 27 26.7 Send a Segment (5/10) Figure 26.27. tcp_output function: set ti_seq, ti_ack, and ti_flags. Decrement snd_nxt if FIN is being retransmitted Set sequence number field of segment 1. No data to send (len = 0) 2. SYN, FIN 모두 set 안됨 3. Persist timer not set // ACK field set Set header length if options present 1. No data to send (len = 0) 2. SYN, FIN 모두 set 안됨 3. Persist timer not set // flags field set
28
Page 28 26.7 Send a Segment (6/10) Figure 26.29. tcp_output function: fill in more TCP header fields and calculate checksum Don ’ t advertise less than one full- sized segment // window size 가 TCP_MAXWIN 보다 클 때 TCP_MAXWIN 으로 set Set urgent offset // snd_up > snd_nxt (urgent pointer 가 존재한다는 것을 의미 ) // (rcv_adv – rcv_nxt) > win 이라면 win 재설정 (sender 의 previously advertised 이므로 ) // pseudo header 에 TCP length 저장 후 checksum
29
Page 29 26.7 Send a Segment (7/10) Figure 26.31. tcp_output function: update sequence number, initialize retransmit timer // ‘ Transmit ’ state 에서 persist 상태가 아니라면 … // startseq 에 sequence number 저장 Remember starting sequence number Increment snd_nxt // SYN, FIN 은 ‘ 1 ’ sequence number 로 처리 update snd_max // snd_nxt > snd_max 라면 … (normal transmission) // snd_max 재설정 // rtt 에 대한 내용이 설정되어있지 않다면 // rtt 에 관련 변수 설정
30
Page 30 26.7 Send a Segment (8/10) Figure 26.31. tcp_output function: update sequence number, initialize retransmit timer (con ’ t) Set retransmission timer // t_rxtcur : current retx timeout // persist timer 가 설정되어있다면 제거 // persist state
31
Page 31 26.7 Send a Segment (9/10) Figure 26.32. tcp_output function: call ip_output to send segment Add trace record for socket debugging Set IP length, TTL, and TOS Pass datagram to IP // socket 에 SO_DEBUG option 이 설정되었다 면 debug 정보 저장 (circular queue, 100 개 ) // TTL // IP total length // TOS // TCP segment 전송 (Ch.8 IP 에서 언급 ) // tcp_quench() : slow start 적용 (buffer full 또는 mbuf allocation 실패 ) // SYN 이후의 EHOSTUNREACH, ENETDOWN 은 soft error 처리
32
Page 32 26.7 Send a Segment (10/10) Figure 26.32. tcp_output function: call ip_output to send segment (con ’ t) Update rcv_adv and last_ack_sent // rcv_nxt + win > rcv_adv 라면 … // rcv_adv 값 수정 // 방금 전송한 segment 에 ACKNOW, DELAK 가 적용되었다면 해당 flag reset // more data to send ? (Fig 26.1 의 again 로 jump)
33
Page 33 26.8 tcp_template Function Connection 에 대해 IP, TCP header 의 template 생성 (This minimizes the amount of work required by tcp_output) Figure 26.33. tcp_template function: create template of IP and TCP headers Allocate mbuf Initialize header fields Pseudo-header for TCP checksum computation
34
Page 34 26.9 tcp_respond Function (1/3) The tcp_respond() is a special-purpose function. Tcp_input() : generate an RST segment(with or without ACK) Tcp_timers() : send a keepalive probe // tcpcb // TCP-IP pseudo header
35
Page 35 26.9 tcp_respond Function (2/3) Figure 26.34. tcp_respond function: first half Send keepalive probe when keepalive timer expires // mbuf allocation // keepalive probe 이므로 length 는 0 Send RST segment in response to received segment // received segment 에서 첫번째 mbuf 이후의 mbuf chain 을 free(mbuf 재사용 ) // src, dst IP addr 과 dport, sport 를 바꾸기 위한 macro
36
Page 36 26.9 tcp_respond Function (3/3) Figure 26.36. tcp_respond function: second half // tcp_template() 와 유사 // 각 field set // checksum 실행 // ip_output()
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.