Skip to content
LIVE FEED

BlogSCTP + Diameter — Tri thức tổng hợp (trọng tâm leg DEA → HSS / S6a)

Bố cục bài viết

Trang này

Sunex 31/07/2026 · 17 phút đọc

Ngày tạo

31/07/2026

Cập nhật

Lượt xem

9

Đọc

17m

SCTP + Diameter — Tri thức tổng hợp (trọng tâm leg DEA → HSS / S6a)

Tài liệu tham chiếu code-free. Gồm 4 phần: A. SCTP (tầng transport) · B. Diameter (tầng ứng dụng) · C. Cách hai tầng phối hợp — phần cốt lõi để debug · D. Cấu hình & xử lý sự cố DEA→HSS.

Chuẩn liên quan: RFC 9260 (SCTP), RFC 6733 (Diameter base), RFC 3539 (watchdog), 3GPP TS 29.272 (S6a/S6d).


PHẦN A — SCTP (tầng transport)

SCTP là giao thức transport, IP protocol number 132, ngang hàng TCP/UDP, được thiết kế cho báo hiệu telecom. Hai tính năng “đắt giá”: multi-homing (dự phòng đường truyền) và multi-streaming (chống head-of-line blocking).

A.0 Đặc điểm SCTP & so sánh chi tiết với TCP

SCTP kế thừa “độ tin cậy + kiểm soát tắc nghẽn” của TCP nhưng thêm bốn trục đặc trưng. Hiểu cơ chế bên trong (không chỉ tên tính năng) mới debug được leg báo hiệu.

1) Định hướng bản tin (message-oriented) vs dòng byte (byte-stream). TCP là dòng byte: gửi 100 + 100 byte, bên nhận có thể đọc thành 1 khối 200 byte hoặc 3 khối tùy ý → ứng dụng phải tự đóng khung (length-prefix/delimiter). Đó là lý do Diameter-over-TCP phải đọc 20 byte header lấy Message Length rồi mới đọc tiếp. SCTP giữ nguyên biên bản tin: một lần gửi = một bản tin giao nguyên vẹn → bớt một tầng framing.

2) Multi-streaming & head-of-line (HOL) blocking. TCP chỉ có một dòng thứ tự duy nhất: một segment rớt → mọi byte đến sau (dù thuộc giao dịch khác) đều kẹt chờ retransmit. SCTP chia nhiều stream, mỗi stream thứ tự riêng → rớt ở stream 1 không chặn stream 2. ⚠ HOL chỉ được khử giữa các stream; trong cùng một stream vẫn còn thứ tự. Dồn mọi thứ vào stream 0 = quay về kiểu TCP.

3) Multi-homing. TCP gắn chặt một cặp IP nguồn–đích; IP chết = connection chết, ứng dụng thấy “broken pipe” và phải tự kết nối lại. SCTP gắn nhiều IP vào một association, chuyển path là việc của transport, trong suốt với ứng dụng → đây là nền tảng carrier-grade HA. (TCP muốn tương đương phải dùng MPTCP — hiếm trong core network.)

4) Bắt tay & chống tấn công mù. TCP bắt tay 3 bước, server cấp TCB ngay khi nhận SYN → dễ SYN flood. SCTP bắt tay 4 bước, server stateless tới COOKIE-ECHO nhờ State Cookie ký HMAC → kháng flood (đổi lại thêm ~1 RTT, nhưng COOKIE-ECHO ghép được DATA nên ít thiệt). Chống injection mù: TCP dựa vào đoán sequence number (lịch sử từng yếu); SCTP thêm Verification Tag 32-bit mỗi chiều — gói sai tag bị bỏ.

5) Giao nhận & độ tin cậy linh hoạt. TCP luôn tin cậy + đúng thứ tự, không có lựa chọn khác. SCTP hỗ trợ unordered delivery (bit U) và partial reliability (PR-SCTP, RFC 3758 — bản tin có thể “hết hạn” và bỏ qua nếu trễ).

6) Đóng kết nối. TCP có half-close (một chiều FIN, chiều kia vẫn gửi) và RST thô bạo. SCTP không có half-close: SHUTDOWN đóng cả hai chiều (3 bước êm) hoặc ABORT (gấp).

7) Toàn vẹn & giám sát đường. Checksum: TCP 16-bit ones-complement (yếu); SCTP CRC32c 32-bit (mạnh hơn nhiều) — ⚠ NIC offload CRC32c hay lỗi gây mất gói âm thầm. SCTP có HEARTBEAT built-in giám sát từng path; TCP keepalive chỉ là tùy chọn thô. Congestion control: TCP per-connection, SCTP per-path (mỗi path cwnd/ssthresh riêng).

8) Cái giá thực tế. TCP được hỗ trợ khắp nơi; SCTP (proto 132) hay bị firewall chặn, không NAT traversal, nhiều LB L4 không cân bằng được → đây là lý do thực tế khiến một số triển khai Diameter vẫn chọn TCP dù SCTP ưu việt hơn về kỹ thuật.

Bảng so sánh cô đọng

Tiêu chíTCPSCTP
Đơn vị dữ liệudòng byte (tự đóng khung)bản tin (giữ biên)
Luồng song song1 (HOL blocking)nhiều stream (khử HOL chéo stream)
Đa địa chỉ1 cặp IPmulti-homing, failover trong suốt
Bắt tay3 bước, dễ SYN flood4 bước + cookie, kháng flood
Chống injectionsequence number+ Verification Tag 32-bit
Độ tin cậyđầy đủ, đúng thứ tự+ unordered + partial (PR-SCTP)
Đóngcó half-close, RSTkhông half-close; SHUTDOWN/ABORT
Checksum16-bitCRC32c 32-bit
Giám sát đườngkeepalive thôHEARTBEAT per-path
Congestion controlper-connectionper-path
Hỗ trợ middleboxphổ cậphay bị chặn, không NAT

A.1 Association (không gọi là “connection”)

  • Một endpoint = nhiều địa chỉ IP + một port.
  • Một association bao trùm mọi path giữa các IP của hai bên — chỉ cần MỘT association.
        Host A                                Host Z
   ┌──────────────┐                      ┌──────────────┐
   │ IP A1 ───────┼─── path 1 (primary) ─┼──► IP Z1     │
   │ IP A2 ───────┼─── path 2 (backup) ──┼──► IP Z2     │
   └──────────────┘                      └──────────────┘
          └─────────── MỘT association duy nhất ─────────┘
   HEARTBEAT giám sát path nhàn rỗi → path chết thì failover, association không đứt.

A.2 Bắt tay 4 bước (chống SYN-flood)

Server KHÔNG cấp phát state (TCB) cho tới bước 3 — nhờ cơ chế State Cookie ký HMAC.

   A (initiator)                          Z (responder)
    │ ──────── INIT (Init Tag=Ta) ──────────► │  Z chưa tạo TCB
    │ ◄─────── INIT-ACK (Init Tag=Tz,         │
    │          State Cookie đã ký) ─────────── │
    │ ──────── COOKIE-ECHO (gửi lại cookie) ─► │  Z xác thực → MỚI tạo TCB
    │ ◄─────── COOKIE-ACK ──────────────────── │
    │ ════════ ASSOCIATION UP ════════════════ │
  • Verification Tag: mỗi chiều một tag riêng; chống blind injection & gói lạc.
  • COOKIE-ECHO được phép ghép DATA → dữ liệu chảy ngay từ bước 3.

A.3 Truyền dữ liệu — TSN ≠ SSN

SốPhạm viDùng cho
TSN (Transmission Sequence Number)toàn associationđộ tin cậy / retransmit / SACK
SID + SSN (Stream Sequence Number)trong từng streamgiữ thứ tự độc lập theo stream

Multi-streaming: rớt 1 message ở stream này KHÔNG chặn stream khác (chống head-of-line blocking).

A.4 Path management & failover

Mỗi destination address có state riêng (ACTIVE/INACTIVE, RTO, cwnd…):

  • HEARTBEAT dò path nhàn rỗi (hb_interval ~30s).
  • path_max_retrans (~5): vượt ngưỡng → path INACTIVE, dồn sang path khác.
  • assoc_max_retrans (~10): vượt ngưỡng → ABORT cả association.

A.5 Đóng association (không có half-close)

SHUTDOWN → SHUTDOWN-ACK → SHUTDOWN-COMPLETE   (đóng êm)
ABORT                                          (đóng gấp)

PHẦN B — Diameter (tầng ứng dụng)

Diameter (RFC 6733) chạy trên SCTP (hoặc TCP), port chuẩn 3868. Trên leg DEA→HSS dùng application S6a/S6d (3GPP TS 29.272), Application-Id = 16777251.

B.1 Các message nền tảng

CặpTênVai trò
CER / CEACapabilities-Exchange Request/Answer“chào hỏi” — chốt application & năng lực chung, BẮT BUỘC trước mọi traffic
DWR / DWADevice-Watchdog Request/Answergiữ nhịp, phát hiện peer chết ở mức ứng dụng (RFC 3539)
DPR / DPADisconnect-Peer Request/Answerchủ động ngắt peer, kèm Disconnect-Cause

B.2 Capabilities Exchange — chỗ “lên hay rớt” được quyết định

Ngay sau khi transport sẵn sàng, initiator phải gửi CER; responder soi rồi trả CEA.

DEA ── CER (Origin-Host, Host-IP-Address×N,
            Vendor-Specific-Application-Id{10415, 16777251},
            Supported-Vendor-Id 10415) ──────────────► HSS
DEA ◄─ CEA (Result-Code = 2001 DIAMETER_SUCCESS) ────── HSS
     → sẵn sàng tải ULR/AIR/IDR/CLR...

Các AVP định danh & năng lực phải khai đúng:

AVPGiá trị mẫuGhi chú
Origin-Hostdea01.epc.mnc001.mcc452.3gppnetwork.orgFQDN, phải khớp cái HSS whitelist
Origin-Realmepc.mnc001.mcc452.3gppnetwork.orgdùng cho realm routing
Host-IP-Addressmọi IP SCTP đang bindphải khớp số IP bind ở SCTP
Vendor-Id104153GPP
Vendor-Specific-Application-Id{10415 + 16777251}quảng bá S6a
Supported-Vendor-Id10415

B.3 Result-Code thường gặp khi bring-up

Code / dấu hiệuNghĩaSửa ở DEA
2001 DIAMETER_SUCCESSOK—
5010 NO_COMMON_APPLICATIONkhông chung applicationthiếu Vendor-Specific-App-Id / Supported-Vendor-Id, hoặc chưa enable S6a cho peer
3010 UNKNOWN_PEERHSS không biết Origin-Host nàysai FQDN / chưa khai peer ở HSS
DPR Disconnect-Cause=2 (DO_NOT_WANT_TO_TALK_TO_YOU)bị từ chốiOrigin-Host DEA chưa được HSS whitelist
ELECTION_LOSTcả hai cùng initiatecấu hình rõ chỉ một bên initiate

B.4 Cấu trúc bản tin Diameter & cách đọc

Một bản tin = header 20 byte + chuỗi AVP. Đọc đúng header là chìa khóa soi pcap.

 0                   1                   2                   3
+-------+-----------------------------------------------------------+
|Version|                 Message Length (24)                       |
+-------+-----------------------------------------------------------+
|Cmd Flg|                  Command Code (24)                        |
+-------+-----------------------------------------------------------+
|                       Application-ID (32)                         |
+------------------------------------------------------------------+
|                   Hop-by-Hop Identifier (32)                     |
+------------------------------------------------------------------+
|                   End-to-End Identifier (32)                     |
+------------------------------------------------------------------+
|  AVPs ...                                                         |

Các trường header:

TrườngÝ nghĩa khi đọc
Versionluôn = 1
Command Flagsbit R = Request(1)/Answer(0); P = Proxiable; E = Error; T = re-transmit. Đọc R trước tiên
Command Codeloại lệnh — phân biệt request/answer bằng bit R (cùng code)
Application-IDbase = 0 hay S6a = 16777251
Hop-by-Hop IDghép request↔answer giữa hai peer kề (relay dùng để khớp)
End-to-End IDchống trùng lặp xuyên suốt end-to-end; relay không được đổi

⚠ Bẫy hay gặp: CER, DWR, DPR đều mang Application-Id = 0 (base), KHÔNG phải 16777251. Đừng tưởng “không thấy app S6a” là sai — phải nhìn Command Code (257/280/282).

Định dạng AVP:

+------------------------------------------------------------------+
|                          AVP Code (32)                           |
+-------+----------------------------------------------------------+
|V M P..|                  AVP Length (24)                         |
+-------+----------------------------------------------------------+
|            Vendor-ID (32)  ← chỉ có khi V-bit = 1                 |
+------------------------------------------------------------------+
|  Data ...  (pad tới bội số 4 byte; AVP Length KHÔNG tính padding) |
  • V-bit: vendor-specific → có trường Vendor-ID (3GPP = 10415).
  • M-bit (Mandatory): nếu peer không hiểu một AVP có M-bit → phải reject cả bản tin (DIAMETER_AVP_UNSUPPORTED 5001). Đây là nguồn của nhiều reject “khó hiểu”.

Quy trình đọc một bản tin (5 bước):

  1. Header: bit R → request/answer? Command Code → lệnh gì? Application-Id → base(0)/S6a?
  2. Ghép cặp: Hop-by-Hop ID khớp giữa hai peer kề; End-to-End ID khớp xuyên suốt.
  3. AVP định danh: Origin-Host, Origin-Realm, Destination-Host, Destination-Realm.
  4. Nếu là answer: đọc kết quả — Result-Code (AVP 268) HOẶC Experimental-Result (AVP 297).
  5. AVP nghiệp vụ: User-Name (IMSI), Visited-PLMN-Id, ULR-Flags, Subscription-Data…

⚠ Đặc thù 3GPP S6a: lỗi thường trả qua Experimental-Result-Code (trong AVP 297, kèm Vendor-Id 10415), KHÔNG phải Result-Code base. Debug phải nhìn cả hai chỗ.

Command Code cần nhớ (S6a):

LệnhCodeAppMục đích
CER/CEA257base(0)capabilities
DWR/DWA280base(0)watchdog
DPR/DPA282base(0)disconnect
ULR/ULA316S6aUpdate-Location
CLR/CLA317S6aCancel-Location
AIR/AIA318S6aAuthentication-Information
IDR/IDA319S6aInsert-Subscriber-Data
DSR/DSA320S6aDelete-Subscriber-Data
PUR/PUA321S6aPurge-UE
RSR/RSA322S6aReset
NOR/NOA323S6aNotify

Result / Experimental-Result-Code S6a hay gặp:

CodeNghĩa
2001DIAMETER_SUCCESS
5001DIAMETER_ERROR_USER_UNKNOWN (3GPP)
5004DIAMETER_ERROR_ROAMING_NOT_ALLOWED (3GPP)
5420DIAMETER_ERROR_UNKNOWN_EPS_SUBSCRIPTION
5421DIAMETER_ERROR_RAT_NOT_ALLOWED

B.5 Bộ filter soi/lọc bản tin (Wireshark display filter — dùng được cả trong tshark -Y)

Đây là biểu thức filter, áp thẳng vào ô filter của Wireshark.

Tầng SCTP — khoanh vùng handshake/đóng:

FilterBắt được
sctptoàn bộ SCTP
sctp.chunk_type == 1INIT
sctp.chunk_type == 2INIT-ACK
sctp.chunk_type == 10COOKIE-ECHO
sctp.chunk_type == 11COOKIE-ACK
sctp.chunk_type == 7SHUTDOWN (tìm bên nào chủ động đóng)
sctp.chunk_type == 6ABORT (đóng gấp — đọc Error Cause)
sctp.chunk_type == 0DATA (mang bản tin Diameter)

Bộ lọc vàng cho lỗi của bạn (UP rồi đóng mà không CER): sctp.chunk_type == 11 || sctp.chunk_type == 7 || diameter.cmd.code == 257 → thấy COOKIE-ACK có, CER (257) vắng, rồi SHUTDOWN → đúng lỗi vai initiator.

Tầng Diameter — lọc theo lệnh / hướng / lỗi:

FilterBắt được
diametertoàn bộ Diameter
diameter.cmd.code == 257CER/CEA
diameter.cmd.code == 280DWR/DWA
diameter.cmd.code == 282DPR/DPA
diameter.cmd.code == 316ULR/ULA
diameter.cmd.code == 318AIR/AIA
diameter.flags.request == 1chỉ Request
diameter.flags.request == 0chỉ Answer
diameter.flags.error == 1bản tin có cờ Error
diameter.Result-Code >= 3000mọi answer lỗi (base)
diameter.Experimental-Result-Codelỗi trong vendor space 3GPP
diameter.Origin-Host == "hss01.epc..."theo node nguồn
diameter.User-Name == "452010123456789"theo IMSI
diameter.Session-Id contains "dea01"theo phiên
diameter.avp.code == 1bản tin chứa AVP User-Name

Mẹo đọc nhanh: mở Wireshark, lọc diameter.cmd.code == 257, bung cây AVP của CEA → đọc Result-Code/Experimental-Result + so Vendor-Specific-Application-Id hai bên. Nếu filter này không ra gói nào sau COOKIE-ACK → khẳng định không có CER (lỗi tầng FSM).

B.6 Kiểm tra / lọc bản tin phía DEA (validation — GSMA FS.19)

Ngoài soi pcap, DEA còn chủ động kiểm tra & lọc bản tin như một Diameter firewall ở biên:

  • Kiểm tra AVP bắt buộc: mỗi command có tập AVP mandatory (vd ULR cần User-Name, RAT-Type, ULR-Flags, Visited-PLMN-Id). Thiếu → reject 5005 MISSING_AVP.
  • Nhất quán định danh: Origin-Host/Origin-Realm trong bản tin khớp peer đã thiết lập; Destination-Realm hợp lệ với realm routing table. Lệch → 5003 / 3002 UNABLE_TO_DELIVER.
  • Xử lý M-bit đúng: gặp AVP lạ có M-bit phải reject (5001), không được im lặng bỏ qua.
  • Nhất quán Application-Id: Application-Id trong header khớp Command Code (vd ULR phải đi cùng 16777251). Sai → reject.
  • Lọc biên (whitelist/blacklist AVP): ở hướng đối tác roaming, DEA strip/chặn các AVP nhạy cảm (topology hiding: ẩn Origin-Host nội bộ, lọc Route-Record), chống rò topo mạng lõi.
  • Rate limiting & chống flood: giới hạn tốc độ CER/ULR theo peer để chặn signaling storm.

Với leg DEA→HSS nội bộ (không phải biên roaming): trọng tâm là kiểm tra mandatory AVP + nhất quán định danh/Application-Id; phần strip AVP & topology hiding để dành cho hướng đối tác bên ngoài.


PHẦN C — Hai tầng vai trò (phần cốt lõi để debug)

Đây là điểm hay bị đánh đồng và là nguồn gốc của lỗi “SCTP UP nhưng không có CER”. Diameter có HAI tầng vai trò ĐỘC LẬP — không được trộn:

TầngVai tròĐịnh nghĩaCâu hỏi
Transport (SCTP)client / serverclient gửi INIT (mở association); server listen 3868Ai mở kết nối?
Diameter peer FSMinitiator / responderinitiator gửi CER; responder trả CEAAi gửi CER?
              Mở transport (INIT)?      Gửi CER?
  client            ✅                    —
  server            ❌ (listen)           —
  initiator         —                     ✅
  responder         —                     ❌ (chỉ trả CEA)

C.1 Vì sao dễ nhầm

Theo RFC 6733, bên mở transport (client) thì là initiator và phải gửi CER. Trong happy-path: client = initiator, server = responder → nên dễ nghĩ chúng là một. Nhưng hai tầng có thể lệch nhau do cấu hình, và đó chính là lỗi.

C.2 Bức tranh “happy path” (hai tầng trùng nhau)

   DEA (client + initiator)              HSS (server + responder)
    │ ── INIT ───────────────────────► │   ← DEA mở SCTP (transport)
    │ ◄─ INIT-ACK ─────────────────────│
    │ ── COOKIE-ECHO ────────────────► │
    │ ◄─ COOKIE-ACK ───────────────────│   ← SCTP UP
    │ ── CER ────────────────────────► │   ← DEA initiator phát CER (Diameter)
    │ ◄─ CEA (2001) ───────────────────│   ← HSS responder

C.3 Bức tranh LỖI (hai tầng lệch) — đúng triệu chứng đang gặp

   DEA                                   HSS
    │ ═══ COOKIE-ACK (SCTP UP) ══════════ │   ← transport OK
    │            ⌛ (chờ CER...)            │
    │        ✗ KHÔNG bên nào gửi CER       │   ← DEA không nhận vai initiator
    │ ◄─────────── SHUTDOWN ───────────── │   ← một bên timeout → đóng êm

Diễn giải triệu chứng theo lớp:

Triệu chứng quan sátKết luận
Kẹt ở INIT, không có INIT-ACKtầng transport: firewall chặn proto 132 / CRC32c offload lỗi
SCTP UP → có CER/CEA → CEA lỗi → đóngtầng Diameter: lệch application / Origin-Host (xem Phần B.3)
SCTP UP → KHÔNG có CER → SHUTDOWNtầng Diameter FSM: DEA không được đặt vai initiator

PHẦN D — Cấu hình DEA→HSS & xử lý sự cố

D.1 Sáu nhóm cấu hình tối thiểu trên DEA

  1. Local node: Origin-Host, Origin-Realm, Host-IP-Address (đủ mọi IP), Vendor-Id 10415, listen 3868.
  2. Transport SCTP: chọn SCTP (không phải TCP); local addresses multihomed; OS/MIS streams ≥ 16 (đừng để 1); tune hb_interval / path_max_retrans / assoc_max_retrans / rto.
  3. Peer = HSS: Origin-Host HSS, IP(s) HSS, port 3868, connection mode = initiator, Tw watchdog ~30s, Tc reconnect ~30s.
  4. Application S6a: nạp dictionary 29.272; Application-Id 16777251; khai Vendor-Specific-Application-Id {10415 + 16777251}; Supported-Vendor-Id 10415; enable app cho peer HSS (không chỉ global).
  5. Realm routing table: Destination-Realm epc... → route group HSS; Destination-Host hss01... → peer trực tiếp; action RELAY/PROXY.
  6. Redundancy & bảo mật: route group nhiều HSS có priority/weight; IPsec cho transport (không TLS trên leg nội bộ); ACL chỉ IP HSS; tắt ASCONF; firewall mở proto 132 cho cả hai path, KHÔNG NAT.

D.2 Checklist debug “SCTP UP nhưng không có CER”

Xếp theo xác suất — kiểm đúng thứ tự:

#Kiểm tra trên DEANếu sai → triệu chứng
1Peer HSS đặt connect / initiator mode (chủ động mở + chủ động gửi CER)cả hai chờ nhau, không ai gửi CER ← nghi phạm số 1
2Peer admin-enabled, không standby/disabledSCTP lên nhưng FSM không chạy
3IP/port trong peer khớp IP SCTP thực connectassociation “mồ côi”, không bind vào FSM
4Origin-Host / Origin-Realm / Host-IP-Address đã cấu hìnhkhông build được CER
5App S6a 16777251 gán cho peer HSSstack bỏ qua phát CER
6Đúng process Diameter sở hữu association (không phải LB/health-check/kernel)UP nhưng không thuộc Diameter

D.3 Quy trình xác minh khi bring-up (theo thứ tự)

1. SCTP UP?        INIT → INIT-ACK → COOKIE-ECHO → COOKIE-ACK
                   kẹt ở INIT → firewall proto 132 / CRC32c offload
2. CER đi ra?      KHÔNG → lỗi vai initiator / peer chưa enable (Phần C, D.2)
3. CEA = 2001?     5010 → lệch Application-Id ; 3010 → Origin-Host chưa whitelist
4. DWR/DWA đều?    watchdog OK, peer ở trạng thái OPEN
5. ULR → ULA 2001? leg S6a thông

D.4 Hai gotcha khó debug nhất (kinh nghiệm thực chiến)

  • CRC32c offload lỗi trên NIC: pcap thấy gói đi nhưng không có ACK về → “mất gói ngẫu nhiên”. Tắt SCTP tx-checksum offload để kiểm chứng.
  • Firewall không track multihoming: drop heartbeat/secondary path → path flap. Phải cho qua cả hai path, tuyệt đối không NAT.

Tham chiếu chuẩn

Chủ đềChuẩn
SCTPRFC 9260 (gốc RFC 4960); PR-SCTP 3758; AUTH 4895; ASCONF 5061; I-DATA 8260
Diameter baseRFC 6733 (gốc 3588)
Diameter watchdogRFC 3539
S6a/S6d3GPP TS 29.272 (Application-Id 16777251)
Diameter security (operator)GSMA FS.19
Signalling transport3GPP TS 29.272; SCTP cho S1/NG: TS 36.412 / 38.412
Contact
Facebook
TOP