5 Aralık 2017 Salı

TCP Header

Session ve Flow Farkı
Açıklaması şöyle.
Flow kavramsal olarak IP + port gibi düşünülebilir.

Session ise TCP'nin çalışması için gereken handshake, acknowledge vs. gibi mekanizmaların tamamı gibi düşünülebilir.

TCP Handshake yazısına bakabilirsiniz. TCP sıralamayı korumak zorunda olduğu için, gecikme (latency) açısından UDP'ye göre her zaman daha yavaş kalacaktır.


TCP Header
Şöyledir
0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |       Destination Port        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Sequence Number                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Acknowledgment Number                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Data |           |U|A|P|R|S|F|                               |
| Offset| Reserved  |R|C|S|S|Y|I|            Window             |
|       |           |G|K|H|T|N|N|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Checksum            |         Urgent Pointer        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             data                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Kod ile şöyledir
/* TCP Header */
struct tcpheader {
  u_short tcp_sport;               /* source port */
  u_short tcp_dport;               /* destination port */
  u_int   tcp_seq;                 /* sequence number */
  u_int   tcp_ack;                 /* acknowledgement number */
  u_char  tcp_offx2;               /* data offset, rsvd */
#define TH_OFF(th)      (((th)->tcp_offx2 & 0xf0) >> 4)
  u_char  tcp_flags;
#define TH_FIN  0x01
#define TH_SYN  0x02
#define TH_RST  0x04
#define TH_PUSH 0x08
#define TH_ACK  0x10
#define TH_URG  0x20
#define TH_ECE  0x40
#define TH_CWR  0x80
#define TH_FLAGS        (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
  u_short tcp_win;                 /* window */
  u_short tcp_sum;                 /* checksum */
  u_short tcp_urp;                 /* urgent pointer */
};
TCP zarfında IP numaraları ve TCP paketinin büyüklüğü bilgisi yok. Bu bilgi IP zarfı içindedir.
IP Stack yazılımı IP Numarası + TCP Paketinin büyüklüğü bilgilerini TCP yazılımına verir.
It is clearly nessacery to pass some metadata (size, addresses etc) between the "transport" and "internet" layers but how exactly this is done is an implementation detail.
1. TCP Port Numaraları
Açıklaması şöyle
A port number is a 16-bit unsigned integer, thus ranging from 0 to 65535
1.1 Source Port (16 bits) : Sender's port.
1.2 Destination Port (16 bits) : Receiver's port.
Port numarası 16 bit olduğu için 65535'e kadar gider.

Well-Known Port Numaraları
Bazı port numaraları (0-1024 arası) ayrılmıştır veya atanmış durumda. Well-known port listesi şöyle.

0 Numaralı Port Kullanılamaz
0 numaralı port Well-Know Port numarası içinde ve ayrılmış (reserved) durumda. Yani kullanılamaz. 
Açıklaması şöyle
IANA has reserved both TCP and UDP port 0.
Açıklaması şöyle
Port 0 is reserved by networking libraries (either socket or streams API) to return a random unused port number. All popular OSes do this. If you use port 0 the socket library will give you port 63812 or 23712 or 11328 or 9035 etc. Because of this it is generally impossible for port 0 to appear on the wire (unless you write your own implementation of TCP/IP stack)

Bu portaları dinleyen sunucu çalıştırmak için yönetici (admin) olmak gerekir. Böylece çok kullanıcı işletim sistemlerinden tek bir kullanıcı herkes adına sunucu açamaz.

Registered Port Numaraları
1024 - 4951 arası numaralardır. Sunucular için kullanılır. Sunucu portları IANA'ya kaydettirilebiliyor. Registered port liste şöyle.

Dynamic Port Numaraları
49152 - 65535 arası numaralar dinamik olarak giden (outbound) bağlantılar için kullanılır.

2. Sequence Number (32 bits)
Sequence Number Alanı yazısına taşıdım.

3. Acknowledgement Number (32 bits)
Açıklaması şöyle.
Represents either (if the ACK bit is set) the sequence number of the next expected byte to be received from the sender (defined by the receiver), or (if the ACK bit is not set - only occurs at the beginning of the communication) the acknowledgment of the other end's initial sequence number itself.
4. Data Offset (4 bits)
Açıklaması şöyle.
Specifies the size of the TCP header in the number of 32 bit words, implicitly stating where in the TCP segment the data begins (the offset of data in theTCP segment)
Açıklaması şöyle.
"Data offset specifies the size of the TCP header in 32 bit words. The min. size header is 5 words and the max. is 15 words, thus giving the min. size of 20 bytes and max. of 60 bytes."
Açıklaması şöyle.
The purpose of the data offset is to tell the upper layers where the data starts.
1 word = 4 byte anlamına gelir. Header 20 byte - 60 byte arasında değişebilir. TCP zarfı değişken büyüklükte olduğu için data'nın nerede başladığını belirtmek için kullanılır.

5. Reserved (3 bits)
Açıklaması şöyle
For future use (set to zero)

6. TCP Bayrakları
Bazı TCP bayrakları şunlardır
  • Nonce
  • CWR
  • ECN-ECHO
  • URGENT
  • ACK
  • Push
  • RST
  • SYN
  • FIN
NS Flag - 1 bit
Açıklaması şöyle
Explicit Congestion Notification  (ECN)-nonce concealment protection.
Açıklaması şöyle
ECN is used by TCP to inform the hosts about network congestion.
CWR Flag - 1 bit
Açıklaması şöyle
If set, the Congestion Window Reduced (CWR) flag notifies the receiver that the sender has received an ECE flag and has reduced the congestion window as a result.

ECE - 1 bit
Açıklaması şöyle
When the SYN bit is set, ECN-Echo  (ECE) indicates whether TCP peer is ECN capable.  If the SYN bit is not set, a set ECE field indicates that a packet with the Congestion Experienced flag in the IP header set is received during normal transmission.

URG Flag - 1 bit
Açıklaması şöyle
Indicates that the Urgent pointer field is valid.
Bu bayrak artık pek kullanılmıyor.

ACK - 1 bit
Açıklaması şöyle
Indicates that the Acknowledgment field is valid. (Should be set in all packets after the initial SYN packet sent by the client. )
ACK biti atanmış ise Acknowledgment alanı bir sonraki beklenen paket numarasını belirtir. Açıklaması şöyle
If the ACK flag is set then the value of this field is the next sequence number that the sender is expecting.
ACK Ne Kadar Yük Getirir
Eğer veri iki yönlü ise ACK çok az yük getirir. Açıklaması şöyle
If data is flowing both ways, the ACKs are free since the ACK information rides in the same packets as the data.
Yani şu anlama gelir.
The receiver sends one message instead of two.
PSH (PUSH) Flag - 1 bit
Açıklaması şöyle
If set, requests the receiver to push the buffered data to the receiving application.
Paketin hemen gönderilmesi ve işlenmesi için kullanılır. Http Get isteğinde bu bayrak kullanılabilir.

RST (Reset) Flag -  1 bit
RST (Reset) Flag yazısına taşıdım.

SYN Flag - 1 bit
Açıklaması şöyle
If set means that the sender has finished sending data, and there will be no more data from the sender.

TCP Handshake yazısına bakabilirsiniz.

FIN Flag - 1 bit
Açıklaması şöyle
If set means that the sender has finished sending data,  and there will be no more data from the sender.
[FIN,ACK] bayrakları genelde sunucu socketlerde kullanılır. Socketin gönderme kısmının kapatıldığını belirtir. Socket okuma yapmaya devam edebilir. FIN mesajını alan tarafın yapabileceği bir şey yoktur. Aynı telefonun kapanması gibi karşı taraf kendi gönderme kısmını artık kapatmıştır.

7. Window Size - 16 bits
Açıklaması şöyle.
Set by the receiver. Announces the maximum number of bytes  (beyond the current ACK-ed sequence number) that the receiver is currently willing to receive.
8. Checksum - 16 bits
Açıklaması şöyle.
Used for controlling if header and data contain errors.
Hesaplanan checksum ile alınan checksum tutmuyorsa paket kabul edilmez. Açıklaması şöyle.
When TCP packet is received at the destination, the receiving TCP code also performs the TCP calculation and see if there’s a mismatch. If there is, it means there’s error in the packet and it will be discarded. The same validation logic used for IP header checksum validation can be used.
Eğer TCP bugün tasarlansaydı belki 32 veya 64 bit CRC kullanırdı. Açıklaması şöyle.
TCP has 16-bit whole data checksum protecting some parts of the IPv4 header, TCP header and all of the data. This is a true end-to-end checksum calculated using the same algorithm as IPv4 header checksum. Unfortunately, there is one in 65536 chance of accepting random corruption, meaning that 64 megabytes of randomly corrupted data sent will be once accepted given a kilobyte segment size.
Kod olarak şöyledir.
struct pseudo_tcp
{
  unsigned saddr, daddr;
  unsigned char mbz;
  unsigned char ptcl;
  unsigned short tcpl;
  struct tcpheader tcp;
  char payload[PACKET_LEN];
};
Şöyle yaparız.
/****************************************************************************
  TCP checksum is calculated on the pseudo header, which includes the 
  the TCP header and data, plus some part of the IP header. Therefore, 
  we need to construct the pseudo header first.
*****************************************************************************/
unsigned short calculate_tcp_checksum(struct ipheader *ip)
{
  struct tcpheader *tcp = (struct tcpheader *)((u_char *)ip + 
                             sizeof(struct ipheader)); 

  int tcp_len = ntohs(ip->iph_len) - sizeof(struct ipheader);

  /* pseudo tcp header for the checksum computation */
  struct pseudo_tcp p_tcp;
  memset(&p_tcp, 0x0, sizeof(struct pseudo_tcp));

  p_tcp.saddr  = ip->iph_sourceip.s_addr;
  p_tcp.daddr  = ip->iph_destip.s_addr;
  p_tcp.mbz    = 0;
  p_tcp.ptcl   = IPPROTO_TCP;
  p_tcp.tcpl   = htons(tcp_len);
  memcpy(&p_tcp.tcp, tcp, tcp_len);

  return  (unsigned short)in_cksum((unsigned short *)&p_tcp, tcp_len + 12); 
}
Daha sonra şöyle yaparız.
unsigned short in_cksum(unsigned short *buf,int length)
{
  unsigned short *w = buf;
  int nleft = length;
  int sum = 0;
  unsigned short temp=0;

  /*
  * The algorithm uses a 32 bit accumulator (sum), adds
  * sequential 16 bit words to it, and at the end, folds back all the
  * carry bits from the top 16 bits into the lower 16 bits.
  */
  while (nleft > 1)  {
    sum += *w++;
    nleft -= 2;
  }

  /* treat the odd byte at the end, if any */
  if (nleft == 1) {
    *(u_char *)(&temp) = *(u_char *)w ;
    sum += temp;
  }

  /* add back carry outs from top 16 bits to low 16 bits */
  sum = (sum >> 16) + (sum & 0xffff);     // add hi 16 to low 16 
  sum += (sum >> 16);                     // add carry 
  return (unsigned short)(~sum);
}
9. Options
9.1 No Op
Padding amaçlı kullanılabilir. Bir sonraki bayrağın 16 bit'lik word'den başlaması için boşluğu doldurur.
This option code may be used between options, for example, to align the beginning of a subsequent option on a word boundary. There is no guarantee that senders will use this option, so receivers must be prepared to process options even if they do not begin on a word boundary.
9.2 Maximum Segment Size - 32 bit
MSS alanı SYN aşamasında gönderilir. TCP Handshake yazısına bakabilirsiniz.

9.3 Window Scaling
Açıklama yaz.

9.4 SACK Permitted
SACK Permitted yazısına taşıdım

9.5 Timestamps
Açıklama yaz



Hiç yorum yok:

Yorum Gönder