Các giải thuật TCP đƣợc cài đặt trong phần Networking của nhân Linux. Bởi vì Linux là mã nguồn mở nên cho phép ta có thể chỉnh sửa các giải thuật sao cho nó hoạt động theo ý mình. Trƣớc khi bắt đầu cài đặt giải thuật đề xuất DCTCP-FA, ta tìm hiểu về giải thuật TCP trong mã nguồn nhân Linux, phiên bản 3.2.18.
Phát hiện tắc nghẽn
Giống nhƣ giải thuật DCTCP, về cơ bản giải thuật mới đề xuất này giữ nguyên hầu hết các pha trong mô hình quản lý tắc nghẽn của TCP.
Nếu nhƣ trong TCP, khi bên nhận nhận đƣợc các gói tin bị đánh dấu cờ CE trong phần IP Header thì nó sẽ gửi các gói tin ACK với cờ ECE trong phần TCP Header
48
cho đến nào khi nhận đƣợc phản hồi là cờ CWR trong phần TCP Header thông báo rằng Sender đã giảm cửa sổ tắc nghẽn.
Thì với giải thuật mới DCTCP-FA cũng nhƣ DCTCP, bên nhận nhận đƣợc bao nhiêu gói tin bị đánh dấu cờ CE trong phần IP Header thì sẽ gửi đi bấy nhiêu gói tin ACK với cờ ECE trong phần TCP Header. Và tại bên nhận áp dụng kĩ thuật gửi ACK gộp, nếu nhƣ nhận đƣợc 2 gói tin bị đánh dấu CE liên tiếp thì nó chỉ gửi đi 1 ACK với cờ ECE thôi hoặc nếu nhận đƣợc 2 gói tin không bị đánh dấu liên tiếp thì nó chỉ gửi đi 1 ACK không có cờ ECE. Hàm TCP_ECN_check_ce() làm nhiệm vụ kiểm tra bit CE trong phần IP Header sẽ đƣợc thay thế bởi hàm TCP_ECN_dctcp_check_ce() đƣợc minh họa nhƣ dƣới đây:
Algorithm 1: TCP_ECN_dctcp_check_ce( )
if IP_flags is CE
if ce_state=0 and ACK is delayed
send ACK of previous packet without ECE set ce_state=1
set CWR in TCP_flags else
if ce_state=1 and ACK is delayed send ACK of previous packet with ECE ce_state = 0
set not CWR in TCP_flags
Để sử dụng kĩ thuật ACK gộp, một biến ce_state đƣợc sử dụng để lƣu trạng thái của gói tin vừa nhận có bị đánh dấu CE trong phần IP Header không.
49
Tính toán độ ƣu tiên
Khi nhận đƣợc gói tin ACK với cờ ECE thì bên nhận sẽ không giảm cửa sổ gửi đi một nửa nhƣ giải thuật TCP mà nó giảm theo giá trị αp
, giá trị này biểu diễn mức độ tắc nghẽn trong mạng và độ ƣu tiên của luồng.
Giá trị α đƣợc tính theo công thức: α = (1-g)α + gF, trong đó g=1/16 còn F là tỷ lệgói tin bị đánh dấu CE trong phần IP Header.
Chú ý là nhân Linux đƣợc viết bằng ngôn ngữ C, tuy nhiên nó không dựa vào các thƣ viện chuẩn C nên một số hàm chuẩn của C không đƣợc hỗ trợ , do đó các phép toán nhƣ phép tính dấu phẩy động, hàm mũ không đƣợc phép dùng.
Vì vậy, các giá trị của α, F, p đƣợc tính và biểu diễn theo thang 1024.
Hàm tcp_ack() làm nhiệm vụ kiểm tra các gói tin ACK, do đó ta có thể tính đƣợc Flà tỷ lệ gói tin bị đánh dấu ECN thông qua tỷ lệ gói tin ACK bị đánh dấu cờ ECE ở phần TCP Header. Giá trị của α đƣợc cập nhật sau mỗi khoảng thời gian RTT. Ta cũng tính đƣợc lƣợng thông tin mà luồng đã truyền flow_size, từ đó cho phép ta xác định độ ƣu tiên của luồng flow_priority. Chi tiết về giải thuật đƣợc minh họa nhƣ dƣới đây: Algorithm 2: tcp_ack() if TCP_flag is ECE acked_bytes_ecn += acked_bytes; acked_bytes_total += acked_bytes; flow_size += acked_bytes; if flow_size < 200KB flow_priority = pmax; else if flow_size > 1MB
50 flow_priority = pmin;
else
flow_priority = pmin + (pmax- pmin)(1000-pmin)/800; if RTT expired
F = ack_bytes_ecn*1024/ acked_bytes_total; alpha = alpha + (F-alpha)/16;
Tính toán lại cwnd
Khi có tắc nghẽn thì bên gửi nhận đƣợc các gói tin ACK bị đánh dấu ECE trong phần TCP Header. Bên gửi chỉ giảm cửa sổ tắc nghẽn đi 1 lần duy nhất trong mỗi khoảng thời gian RTT bằng cách gọi hàm tcp_enter_cwr().
Giá trị cửa sổ tắc nghẽn khi giảm có công thức: cwnd = cwnd (1- αp
/2). Giá trị này đƣợc tính bằng cách sử dụng xấp xỉ Bernoulli. Giải thuật đƣợc minh họa nhƣ dƣới đây:
Algorithm 3: tcp_enter_cwr()
cwnd=cwnd–cwnd*alpha/(2*(alpha+priority)-alpha*priority/512) snd_cwnd = max(cwnd,2);
Sau khi thay đổi mã nguồn của giải thuật TCP trong nhân Linux phiên bản 3.2.18. ta tạo ra bản Patch bằng công cụ diff. Chức năng của bản Patch này cho phép áp dụng những thay đổi của giải thuật mới lên mã nguồn ban đầu. Tiến hành build mã nguồn này để cài đặt giải thuật mới, tƣơng tự nhƣ DCTCP.