Chính xác thì PMTUD được thực hiện khi nào? (Khám phá đường dẫn MTU)


21

Trong các cuộc thảo luận xuất phát từ các câu hỏi khác trên trang web này , tôi nhận ra rằng tôi không có hiểu biết vững chắc về việc khi nào Khám phá Đường dẫn MTU (PMTUD) được thực hiện.

Tôi biết những gì nó làm - khám phá MTU thấp nhất trên đường dẫn từ Máy khách đến Máy chủ).
Tôi biết nó hoạt động như thế nào - gửi các gói lớn hơn dần dần với tập bit "Không phân mảnh" của chúng và xem mức độ lớn của gói bạn có thể vượt qua mà không gặp phải lỗi "ICMP Need to Fragment".

Câu hỏi của tôi là cụ thể sau đó, khi nào một máy chủ sẽ thực hiện PMTUD?

Tôi đang tìm kiếm trường hợp cụ thể. Không chỉ là một cái gì đó chung chung như "khi một máy chủ muốn khám phá đường dẫn MTU". Điểm thưởng nếu bạn có thể cung cấp gói chụp của máy chủ đang thực hiện hoặc cung cấp hướng dẫn để tạo gói chụp như vậy.

Ngoài ra, tôi đặc biệt đề cập đến IPv4. Tôi biết trong các bộ định tuyến tạm thời IPv6 không chịu trách nhiệm phân mảnh và có thể tưởng tượng rằng PMTUD xảy ra phổ biến hơn nhiều. Nhưng hiện tại, tôi đang tìm kiếm các ví dụ cụ thể về PMTUD trong IPv4. (mặc dù nếu gói chụp duy nhất bạn có thể kết hợp PMTUD là IPv6, tôi vẫn muốn thấy nó)


PMTUD có được thực hiện từ MTU được hỗ trợ thấp nhất đến cao nhất không? Hoặc thiết bị thực hiện PMTUD trước tiên thử MTU lớn nhất và sau đó bước xuống theo mức tăng lớn cho đến khi gói đi qua và sau đó tăng lên theo mức tăng nhỏ hơn, sau đó luân phiên qua lại cho đến khi xác định cuối cùng được đưa ra?
cpt_fink

@cpt_fink, có một vài chiến lược. Các triển khai hiện đại của thông điệp Cần phân mảnh ICMP bao gồm trong chính tải trọng ICMP là MTU của liên kết cần phân mảnh. Điều đó làm cho nó dễ dàng, vì máy chủ bắt đầu biết ngay MTU là gì. Các triển khai cũ hơn phải sử dụng các chiến lược khác nhau để 'tìm kiếm' cho MTU phù hợp để sử dụng. Các chiến lược này được phác thảo trong RFC1191 trong Phần 5. Chúng bao gồm từ tự động mặc định đến Tối thiểu IP (576), đến sử dụng bảng MTU 'chung' để tìm kiếm hiệu quả hơn (xem RFC1191 Mục 7.1).
Eddie

2
Đây là một câu hỏi thú vị. Tôi đã thực hiện một số hoạt động đào trên PMTUD và tìm thấy điều này. Mặc dù nó đã cũ, tôi quyết định trả lời vì tôi có cùng một câu hỏi và sau vài giờ nghiên cứu tôi có thể đưa ra một câu trả lời khá hay (tôi đoán vậy). Tôi sẽ cố gắng cập nhật và hỗ trợ câu trả lời của tôi với một gói chụp vào ngày mai, nếu có thể.
Filipe Gonçalves

Câu trả lời:


15

Câu trả lời rất đơn giản: bất cứ khi nào chủ nhà hài lòng. Có thật không. Nó đơn giản mà.

Giải thích bên dưới giả định môi trường chỉ có IPv4, do IPv6 không phân mảnh trong các bộ định tuyến (buộc máy chủ phải luôn xử lý phân mảnh và phát hiện MTU).

Không có quy tắc nghiêm ngặt nào chi phối khi (hoặc thậm chí nếu) một máy chủ thực hiện Path MTU Discovery. Lý do mà PMTUD nổi lên là sự phân mảnh được coi là có hại vì nhiều lý do. Để tránh phân mảnh gói, khái niệm PMTUD được đưa vào cuộc sống như một cách giải quyết. Tất nhiên, một hệ điều hành đẹp nên sử dụng PMTUD để giảm thiểu sự phân mảnh.

Vì vậy, một cách tự nhiên, ngữ nghĩa chính xác khi PMTUD được sử dụng phụ thuộc vào hệ điều hành của người gửi - đặc biệt là việc triển khai ổ cắm. Tôi chỉ có thể nói cho trường hợp cụ thể của Linux, nhưng các biến thể UNIX khác có lẽ không khác lắm.

Trong Linux, PMTUD được điều khiển bởi IP_MTU_DISCOVERtùy chọn ổ cắm. Bạn có thể truy xuất trạng thái hiện tại của nó bằng getsockopt(2)cách chỉ định cấp độ IPPROTO_IPIP_MTU_DISCOVERtùy chọn. Tùy chọn này chỉ hợp lệ cho SOCK_STREAMcác ổ cắm ( SOCK_STREAMổ cắm là ổ cắm hai chiều, hướng kết nối, đáng tin cậy; trong thực tế, đó là ổ cắm TCP, mặc dù có thể có các giao thức khác) và khi được đặt, Linux sẽ thực hiện PMTUD chính xác như được định nghĩa trong RFC 1191.

Lưu ý rằng trong thực tế, PMTUD là một quá trình liên tục; các gói được gửi với tập bit DF - bao gồm các gói bắt tay 3 chiều - bạn có thể coi đó là thuộc tính kết nối (mặc dù việc triển khai có thể sẵn sàng chấp nhận một mức độ phân mảnh nhất định tại một số điểm và ngừng gửi gói với DF thiết lập bit). Do đó, PMTUD chỉ là hệ quả của thực tế là mọi thứ trên kết nối đó đang được gửi với DF.

Nếu bạn không đặt IP_MTU_DISCOVERthì sao?

Có một giá trị mặc định. Theo mặc định, IP_MTU_DISCOVERđược kích hoạt trên SOCK_STREAMổ cắm. Điều này có thể được đọc hoặc thay đổi bằng cách đọc /proc/sys/net/ipv4/ip_no_pmtu_disc. Giá trị 0 có nghĩa IP_MTU_DISCOVERlà được bật theo mặc định trong các ổ cắm mới; một số không có nghĩa là ngược lại.

Những gì về ổ cắm không kết nối?

Điều này là khó khăn vì các ổ cắm không kết nối, không đáng tin cậy không truyền lại các phân đoạn bị mất. Trách nhiệm của người dùng là đóng gói dữ liệu theo các khối có kích thước MTU. Ngoài ra, người dùng dự kiến ​​sẽ thực hiện các truyền lại cần thiết trong trường hợp Thông báo lỗi quá lớn . Vì vậy, về cơ bản mã người dùng phải thực hiện lại PMTUD. Tuy nhiên, nếu bạn sẵn sàng cho thử thách, bạn có thể buộc bit DF bằng cách chuyển IP_PMTUDISC_DOcờ tới setsockopt(2).

Điểm mấu chốt

  • Máy chủ quyết định khi nào (và nếu) sử dụng PMTUD
  • Khi nó sử dụng PMTUD, nó giống như một thuộc tính kết nối, nó xảy ra liên tục (nhưng tại bất kỳ thời điểm nào, việc triển khai là miễn phí để ngừng làm như vậy)
  • Các hệ điều hành khác nhau sử dụng các cách tiếp cận khác nhau, nhưng thông thường, các ổ cắm hướng kết nối, đáng tin cậy thực hiện PMTUD theo mặc định, trong khi các ổ cắm không kết nối, không đáng tin cậy thì không

4

Thông thường, phát hiện đơn vị truyền tối đa đường dẫn (PMTUD) xảy ra bất cứ khi nào máy chủ nghĩ rằng gói bị bỏ do quá lớn.

Điều này có thể là để đáp ứng với phân mảnh ICMP cần thiết (loại 3, mã 4) phản hồi rõ ràng cho thấy gói bị bỏ. Trong thực tế điển hình, tất cả các gói IPv4 được đặt với cờ "không phân đoạn" (DF), do đó, bất kỳ gói nào vượt quá MTU sẽ gợi ra phản hồi như vậy. IPv6 hoàn toàn không hỗ trợ phân mảnh.

Một số bộ định tuyến hoặc tường lửa máy chủ bỏ tất cả ICMP thường xuyên vì một quản trị viên ngây thơ tin rằng ICMP là một rủi ro bảo mật . Hoặc, một số sơ đồ tổng hợp liên kết có thể phá vỡ phân phối ICMP . Một cơ chế thay thế để khám phá MTU đã bị vượt quá, không phụ thuộc vào ICMP được đề xuất trong RFC4821 .

tracepathlà công cụ Linux yêu thích của tôi để thăm dò MTU. Dưới đây là ví dụ từ máy chủ có MTU 9001 trên mạng LAN, nhưng phải đi qua VPN IPsec để đạt 10.33.32.157:

$ tracepath -n 10.33.32.157
 1?: [LOCALHOST]                                         pmtu 9001
 1:  10.1.22.1                                             0.122ms pmtu 1500
 1:  169.254.3.1                                           1.343ms pmtu 1422
 1:  10.255.254.61                                        23.790ms 
 2:  no reply
^C [this host won't return an ICMP port unreachable, so tracepath won't terminate]

Các lỗi ICMP có thể được quan sát với tcpdump:

$ sudo tcpdump -p -ni eth0 'icmp and icmp[0] == 3 and icmp[1] == 4'
14:46:57.313690 IP 10.1.22.1 > 10.1.22.194: ICMP 10.33.32.157 unreachable - need to frag (mtu 1500), length 36
14:46:57.315080 IP 169.254.3.1 > 10.1.22.194: ICMP 10.33.32.157 unreachable - need to frag (mtu 1422), length 556

Khám phá MTU được lưu trữ. Trong Linux, điều này có thể được quan sát và xóa sạch ip(hãy cẩn thận với những thay đổi kể từ Linux 3.6 ):

$ ip route get 10.33.32.157
10.33.32.157 via 10.1.22.1 dev eth0  src 10.1.22.194 
    cache  expires 591sec mtu 1422
$ sudo ip route flush cache
$ ip route get 10.33.32.157
10.33.32.157 via 10.1.22.1 dev eth0  src 10.1.22.194 
    cache

Đối với TCP, vượt quá MTU có thể tránh được như là một phần của thiết lập kết nối. Bao gồm trong SYN được gửi bởi mỗi đầu là kích thước phân đoạn tối đa (MSS). Tiêu đề TCP (20 byte không bao gồm tùy chọn ) và tiêu đề IP (20 byte) có nghĩa là MSS và MTU có liên quan bởi sự khác biệt 40 byte.

Dưới đây là ví dụ về thiết lập kết nối giữa hai máy chủ này khi truyền tệp lớn với scp:

$ sudo tcpdump -p -ni eth0 'host 10.33.32.157 and tcp[13]&2 == 2'
IP 10.1.22.194.45853 > 10.33.32.157.22: Flags [S], seq 634040018, win 26883, options [mss 8961,sackOK,TS val 10952240 ecr 0,nop,wscale 7], length 0
IP 10.33.32.157.22 > 10.1.22.194.45853: Flags [S.], seq 1371736848, ack 634040019, win 26847, options [mss 1379,sackOK,TS val 10824267 ecr 10952240,nop,wscale 7], length 0

Trong gói đầu tiên, máy chủ lưu trữ cục bộ đề xuất MSS là 8961. Đây là MTU 9001 được cấu hình, ít hơn 40 byte. SYN / ACK được trả về có MSS là 1379, ngụ ý MTU là 1419. Tôi tình cờ biết trong mạng này máy chủ từ xa cũng đã gửi 8961, nhưng giá trị đã được sửa đổi bởi bộ định tuyến vì nó biết đường dẫn bao gồm đường dẫn internet ( MTU 1500) một chi phí từ một đường hầm IPsec. Bộ định tuyến này cũng đã sửa đổi MSS gửi 8961 của chúng tôi để xuất hiện là 1419 tại máy chủ khác. Điều này được gọi là kẹp MSS .

Vì vậy, theo một nghĩa nào đó, PMTUD đang diễn ra mọi lúc. Trong thực tế, điều đó thực sự có thể xảy ra, nếu kẹp MSS được đặt đúng chỗ và tất cả lưu lượng truy cập xảy ra trên TCP hoặc nếu không có bộ định tuyến nào có MTU nhỏ hơn cấu hình trên các điểm cuối. Ngay cả khi không có MSS kẹp, nó chỉ có thể xảy ra hiếm khi, khi bộ đệm hết hạn.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.