背景知識
UPnP, Universal Plug and Play,中文是 “通用即插即用”。在理解 UPnP 之前,我們先了解一下傳統(tǒng)的 PnP 技術(shù),因?yàn)?UPnP 是對于傳統(tǒng) PnP(即插即用)概念的擴(kuò)展。
傳統(tǒng)的 PnP “即插即用”是指 PC 電腦在添加硬件設(shè)備時(shí)可以自動處理的一種標(biāo)準(zhǔn)。在 PnP 技術(shù)出現(xiàn)以前,當(dāng)需要為 PC 電腦安裝新的硬件(比如:聲卡,CD-ROM,打印機(jī))時(shí),這些設(shè)備需要用到 PC 電腦的 DMA 和 IRQ 等資源,為了避免硬件設(shè)備對計(jì)算機(jī)這些資源使用上的沖突,我們就需要手工為新添加的硬件設(shè)備設(shè)置中斷和 I/O 端口(比如,想要為添加的聲卡占用中斷 5,就找一個(gè)小跳線在卡上標(biāo)著中斷 5的針腳上一插)。這樣的操作需要用戶了解中斷和 I/O 端口的知識,并且能夠自己分配中斷地址而不發(fā)生沖突,對普通用戶提出這樣的要求是不切實(shí)際的。
PnP “即插即用”技術(shù)出現(xiàn)以后,可以自動為新添加的硬件分配中斷和 I/O 端口,用戶無須再做手工跳線,也不必使用軟件配置程序。唯一的要求就是操作系統(tǒng)需要支持 PnP 標(biāo)準(zhǔn),同時(shí)所安裝的新硬件也符合 PnP 規(guī)范的。
UPnP 協(xié)議介紹
現(xiàn)在我們講 UPnP,在網(wǎng)絡(luò)世界里,當(dāng)一個(gè)主機(jī)加入網(wǎng)絡(luò)時(shí),其行為模式跟我們上述的添加和刪除設(shè)備是類似的。尤其是在私有網(wǎng)絡(luò)和公網(wǎng)交互的時(shí)候,私有網(wǎng)絡(luò)中的主機(jī)使用的是內(nèi)網(wǎng) IP 地址,是無法被外網(wǎng)的主機(jī)直接訪問的。必須借助 NAT 網(wǎng)關(guān)設(shè)備(本地路由器)把內(nèi)網(wǎng)地址映射到網(wǎng)關(guān)的公網(wǎng)地址上。
簡單來說就是, NAT 網(wǎng)關(guān)設(shè)備擁有一個(gè)公網(wǎng) IP 地址(比如 10.59.116.19),內(nèi)網(wǎng)中的主機(jī)(比如 192.168.1.101)想要與外界通信的話,NAT 網(wǎng)關(guān)設(shè)備可以為其做一個(gè)端口映射(比如:180.59.116.19 :80 —> 192.168.1.101 :80),這樣,外部的主機(jī)發(fā)往 NAT 網(wǎng)關(guān)的數(shù)據(jù)包都會被轉(zhuǎn)發(fā)給內(nèi)網(wǎng)的該主機(jī),從而實(shí)現(xiàn)了內(nèi)網(wǎng)中的主機(jī)與外部主機(jī)的通信。

當(dāng)內(nèi)網(wǎng)中的主機(jī)想要被外界主機(jī)直接訪問(比如開放 80 端口,對外提供 HTTP 服務(wù)),我們就需要在 NAT 設(shè)備中為當(dāng)前主機(jī)手工配置端口映射,如果內(nèi)網(wǎng)中有多臺主機(jī)都想要被外界主機(jī)直接訪問的話,我們必須在同一個(gè) NAT 設(shè)備上為這些主機(jī)分別做端口映射,它們之間不能使用有沖突的端口。這個(gè)過程需要用戶手工一一配置,顯然給用戶帶來了很大的麻煩。

UPnP 技術(shù)標(biāo)準(zhǔn)的出現(xiàn)就是為了解決這個(gè)問題,只要 NAT 設(shè)備(路由器)支持 UPnP,并開啟。那么,當(dāng)我們的主機(jī)(或主機(jī)上的應(yīng)用程序)向 NAT 設(shè)備發(fā)出端口映射請求的時(shí)候,NAT 設(shè)備就可以自動為主機(jī)分配端口并進(jìn)行端口映射。這樣,我們的主機(jī)就能夠像公網(wǎng)主機(jī)一樣被網(wǎng)絡(luò)中任何主機(jī)訪問了。
UPnP 的應(yīng)用場景
UPnP 典型的應(yīng)用場景就是家庭智能設(shè)備的互聯(lián),還有,目前在網(wǎng)絡(luò)應(yīng)用比如 BitTorrent, eMule,IPFS,Ethereum 等使用 P2P 技術(shù)的軟件,UPnP 功能為它們帶來極大的便利。比如:利用 UPnP 能自動的把它們偵聽的端口號映射到公網(wǎng)地址上,這樣,公網(wǎng)上的用戶也能對當(dāng)前的 NAT 內(nèi)網(wǎng)主機(jī)直接發(fā)起連接。
實(shí)現(xiàn) UPnP 所需條件
必須同時(shí)滿足三個(gè)條件:
- NAT 網(wǎng)關(guān)設(shè)備必須支持 UPnP 功能;這是因?yàn)樗枰缪菘刂泣c(diǎn)(239.255.255.250:1900)的角色,控制點(diǎn)提供的是 SSDP 服務(wù)。
- 操作系統(tǒng)必須支持 UPnP 功能;比如 Windows 系列操作系統(tǒng);
- 應(yīng)用程序必須支持 UPnP 功能;比如 Bt、eMule、IPFS, Ethereum 等。
以上三個(gè)條件必須同時(shí)滿足,缺一不可。
注:大多數(shù)路由器都是支持 UPnP 的,有的是默認(rèn)開啟,有的需要手工開啟。

UPnP 這么好,那么我們應(yīng)該立即開啟嗎?
非也,如果我們的電腦并不需要 UPnP 所提供的功能,比如,我們的電腦并不想要對外直接提供服務(wù),也不運(yùn)行上述 P2P 軟件,那么我們就無需開啟 UPnP。因?yàn)橐坏╅_啟 UPnP,就意味著我們把自己的主機(jī)暴露在公網(wǎng)環(huán)境中,任何主機(jī)都可以向我們的電腦發(fā)起連接,NAT 設(shè)備會對所有收到的數(shù)據(jù)包不進(jìn)行任何 authentication 認(rèn)證而轉(zhuǎn)發(fā)給我們的主機(jī),這樣,路由防火墻就會完全失效,我們的主機(jī)就很容易受到惡意的網(wǎng)絡(luò)窺探,感染病毒或者惡意程序的幾率也大大增加。
注:上述 NAT 設(shè)備通常就是指我們本地的路由器。
SSDP 協(xié)議
介紹完了 UPnP 的概況,為了完整性,現(xiàn)在再介紹一下 UPnP 規(guī)范下的 SSDP 協(xié)議,SSDP 全稱是 Simple Service Discover Protocol 簡單服務(wù)發(fā)現(xiàn)協(xié)議,這個(gè)協(xié)議是 UPnP 的核心,在 UPnP 中定義了一組協(xié)議框架,其中有控制點(diǎn),根設(shè)備等概念,UPnP 設(shè)備通過 SSDP 協(xié)議與根設(shè)備(用戶設(shè)備)進(jìn)行交互。SSDP 是應(yīng)用層協(xié)議,使用 HTTPU 和 HTTPMU 規(guī)范,基于 UDP 端口進(jìn)行通信。
SSDP 使用一個(gè)固定的組播地址 239.255.255.250 和 UDP 端口號 1900 來監(jiān)聽其他設(shè)備的請求。
SSDP 協(xié)議的請求消息有兩種類型,第一種是服務(wù)通知,設(shè)備和服務(wù)使用此類通知消息聲明自己存在;第二種是查詢請求,協(xié)議客戶端用此請求查詢某種類型的設(shè)備和服務(wù)。
1)設(shè)備查詢
當(dāng)一個(gè)客戶端接入網(wǎng)絡(luò)的時(shí)候,它可以向一個(gè)特定的多播地址的 SSDP 端口使用 M-SEARCH 方法發(fā)送 “ssdp:discover” 消息。當(dāng)設(shè)備監(jiān)聽到這個(gè)保留的多播地址上由控制點(diǎn)發(fā)送的消息的時(shí)候,設(shè)備將通過單播的方式直接響應(yīng)控制點(diǎn)的請求。
典型的設(shè)備查詢請求消息格式:
M-SEARCH * HTTP/1.1
S:uuid:ijklmnop-7dec-11d0-a765-00a0c91e6bf6
Host:239.255.255.250:1900
Man:"ssdp:discover"
ST:ge:fridge
MX:3
典型的響應(yīng)格式:
響應(yīng)消息應(yīng)該包含服務(wù)的位置信息(Location 或AL頭),ST和USN頭。響應(yīng)消息應(yīng)該包含cache控制信息(max-age 或者 Expires頭)。
HTTP/1.1 200 OK
Cache-Control: max-age= seconds until advertisement expires
S: uuid:ijklmnop-7dec-11d0-a765-00a0c91e6bf6
Location: URL for UPnP description for root device
Cache-Control: no-cache="Ext",max-age=5000
ST:ge:fridge // search target
USN: uuid:abcdefgh-7dec-11d0-a765-00a0c91e6bf6 // advertisement UUID
AL: <blender:ixl><http://foo/bar>
2、設(shè)備通知消息
在設(shè)備加入網(wǎng)絡(luò)時(shí),它應(yīng)當(dāng)向一個(gè)特定的多播地址的 SSDP 端口使用 NOTIFY 方法發(fā)送 “ssdp:alive” 消息,以便宣布自己的存在,更新期限信息,更新位置信息。
(1)ssdp:alive 消息
由于 UDP 協(xié)議是不可信的,設(shè)備應(yīng)該定期發(fā)送它的公告消息。在設(shè)備加入網(wǎng)絡(luò)時(shí),它必須用 NOTIFY 方法發(fā)送一個(gè)多播傳送請求。NOTIFY 方法發(fā)送的請求沒有回應(yīng)消息。
典型的設(shè)備通知消息格式如下:
NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900CACHE-CONTROL: max-age = seconds until advertisement expires
LOCATION: URL for UPnP description for root device
NT: search target
NTS: ssdp:alive
USN: advertisement UUID
(2)ssdp:byebye消息
當(dāng)一個(gè)設(shè)備計(jì)劃從網(wǎng)絡(luò)上卸載的時(shí)候,它也應(yīng)當(dāng)向一個(gè)特定的多播地址的 SSDP 端口使用 NOTIFY 方法發(fā)送 “ssdp:byebye” 消息。但是,即使沒有發(fā)送 “ssdp:byebye” 消息,控制點(diǎn)也會根據(jù) “ssdp:alive” 消息指定的超時(shí)值,將超時(shí)并且沒有再次收到的 “ssdp:alive” 消息對應(yīng)的設(shè)備認(rèn)為是失效的設(shè)備。
典型的設(shè)備卸載消息格式如下:
NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900NT: search target
NTS: ssdp:byebye
USN: advertisement UUID
全文完!
參考資料:
1、SSDP 協(xié)議原文:http://tools.ietf.org/html/draft-cai-ssdp-v1-03
2、UPnP協(xié)議框架:http://www.upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.0.pdf