webrtc P2P之stun協(xié)議介紹

STUN簡介

RFC5389中诞仓,STUN的全稱為Session Traversal Utilities for NAT移袍,即NAT環(huán)境下的會話傳輸工具, 是一種處理NAT傳輸?shù)膮f(xié)議,但主要作為一個工具來服務(wù)于其他協(xié)議塑径。和STUN/RFC3489類似,可以被終端用來發(fā)現(xiàn)其公網(wǎng)IP和端口填具,同時可以檢測端點間的連接性统舀,也可以作為一種保活(keep-alive)協(xié)議來維持NAT的綁定劳景。和RFC3489最大的不同點在于誉简,STUN本身不再是一個完整的NAT傳輸解決方案,而是在NAT傳輸環(huán)境中作為一個輔助的解決方法盟广,同時也增加了TCP的支持闷串。RFC5389廢棄了RFC3489,因此后者通常稱為classic STUN筋量,但依舊是后向兼容的烹吵。而完整的NAT傳輸解決方案則使用STUN的工具性質(zhì),ICE就是一個基于offer/answer方法的完整NAT傳輸方案桨武,如SIP肋拔。

STUN是一個C/S架構(gòu)的協(xié)議,支持兩種傳輸類型玻募。一種是請求/響應(yīng)(request/respond)類型只损,由客戶端給服務(wù)器發(fā)送請求,并等待服務(wù)器返回響應(yīng)七咧;另一種是指示類型(indication transaction)跃惫,由服務(wù)器或者客戶端發(fā)送指示,另一方不產(chǎn)生響應(yīng)艾栋。兩種類型的傳輸都包含一個96位的隨機數(shù)作為事務(wù)ID(transaction ID)爆存,對于請求/響應(yīng)類型,事務(wù)ID允許客戶端將響應(yīng)和產(chǎn)生響應(yīng)的請求連接起來蝗砾;對于指示類型先较,事務(wù)ID通常作為debugging aid使用携冤。

所有的STUN報文信息都含有一個固定頭部,包含了方法闲勺,類和事務(wù)ID曾棕。方法表示是具體哪一種傳輸類型(兩種傳輸類型又分了很多具體類型),STUN中只定義了一個方法菜循,即binding(綁定)翘地,其他的方法可以由使用者自行拓展;Binding方法可以用于請求/響應(yīng)類型和指示類型癌幕, 用于前者時可以用來確定一個NAT給客戶端分配的具體綁定衙耕,用于后者時可以保持綁定的激活狀態(tài)。類表示報文類型是請求/成功響應(yīng)/錯誤響應(yīng)/指示勺远。在固定頭部之后是零個或者多個屬性(attribute)橙喘,長度也是不固定的。

STUN報文結(jié)構(gòu)

STUN報文和大多數(shù)網(wǎng)絡(luò)類型的格式一樣胶逢,是以大端編碼(big-endian)的厅瞎,即最高有效位在左邊。所有的STUN報文都以20字節(jié)的頭部開始初坠,后面跟著若干個屬性磁奖。下面來詳細說說。

STUN報文頭部
STUN頭部包含了STUN消息類型某筐,magic cookie,事務(wù)ID和消息長度冠跷,如下:

   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
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |0 0|     STUN Message Type     |         Message Length        |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                         Magic Cookie                          |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  |                     Transaction ID (96 bits)                  |
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  

最高的2位必須置零南誊,這可以在當(dāng)STUN和其他協(xié)議復(fù)用的時候,用來區(qū)分STUN包和其他數(shù)據(jù)包蜜托。
STUN Message Type 字段定義了消息的類型(請求/成功響應(yīng)/失敗響應(yīng)/指示)和消息的主方法抄囚。雖然我們有4個消息類別,但在STUN中只有兩種類型的事務(wù)橄务,即請求/響應(yīng)類型和指示類型幔托。響應(yīng)類型分為成功和出錯兩種,用來幫助快速處理STUN信息蜂挪。Message Type字段又可以進一步分解為如下結(jié)構(gòu):

 0                 1
 2  3  4 5 6 7 8 9 0 1 2 3 4 5
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
|M |M |M|M|M|C|M|M|M|C|M|M|M|M|
|11|10|9|8|7|1|6|5|4|0|3|2|1|0|
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+  

其中顯示的位為從最高有效位M11到最低有效位M0重挑,M11到M0表示方法的12位編碼。C1和C0兩位表示類的編碼棠涮。比如對于binding方法來說谬哀,0b00表示request,0b01表示indication严肪,0b10表示success response史煎,0b11表示error response谦屑,每一個method都有可能對應(yīng)不同的傳輸類別。拓展定義新方法的時候注意要指定該方法允許哪些類型的消息篇梭。

Magic Cookie 字段包含固定值0x2112A442氢橙,這是為了前向兼容RFC3489,因為在classic STUN中恬偷,這一區(qū)域是事務(wù)ID的一部分悍手。另外選擇固定數(shù)值也是為了服務(wù)器判斷客戶端是否能識別特定的屬性。還有一個作用就是在協(xié)議多路復(fù)用時候也可以將其作為判斷標(biāo)志之一喉磁。

Transaction ID 字段是個96位的標(biāo)識符谓苟,用來區(qū)分不同的STUN傳輸事務(wù)。對于request/response傳輸协怒,事務(wù)ID由客戶端選擇涝焙,服務(wù)器收到后以同樣的事務(wù)ID返回response;對于indication則由發(fā)送方自行選擇孕暇。事務(wù)ID的主要功能是把request和response聯(lián)系起來仑撞,同時也在防止攻擊方面有一定作用。服務(wù)端也把事務(wù)ID當(dāng)作一個Key來識別不同的STUN客戶端妖滔,因此必須格式化且隨機在0~2^(96-1)之間隧哮。
重發(fā)同樣的request請求時可以重用相同的事務(wù)ID,但是客戶端進行新的傳輸時座舍,必須選擇一個新的事務(wù)ID沮翔。

Message Length 字段存儲了信息的長度,以字節(jié)為單位曲秉,不包括20字節(jié)的STUN頭部采蚀。由于所有的STUN屬性都是都是4字節(jié)對齊(填充)的,因此這個字段最后兩位應(yīng)該恒等于零承二,這也是辨別STUN包的一個方法之一榆鼠。

STUN屬性
在STUN報文頭部之后,通常跟著0個或者多個屬性亥鸠,每個屬性必須是TLV編碼的(Type-Length-Value)妆够。其中Type字段和Length字段都是16位,Value字段為為32位表示负蚊,如下:

   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
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |         Type                  |            Length             |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                         Value (variable)                ....
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  

Length字段必須包含Value部分需要補齊的長度神妹,以字節(jié)為單位。由于STUN屬性以32bit邊界對齊家妆,因此屬性內(nèi)容不足4字節(jié)的都會以padding bit進行補齊灾螃。padding bit會被忽略,但可以是任何值揩徊。

Type字段為屬性的類型腰鬼。任何屬性類型都有可能在一個STUN報文中出現(xiàn)超過一次嵌赠。除非特殊指定,否則其出現(xiàn)的順序是有意義的:即只有第一次出現(xiàn)的屬性會被接收端解析熄赡,而其余的將被忽略姜挺。為了以后版本的拓展和改進,屬性區(qū)域被分為兩個部分彼硫。Type值在0x0000-0x7FFF之間的屬性被指定為強制理解炊豪,意思是STUN終端必須要理解此屬性,否則將返回錯誤信息拧篮;而0x8000-0xFFFF之間的屬性為選擇性理解词渤,即如果STUN終端不識別此屬性則將其忽略。目前STUN的屬性類型由IANA維護串绩。

這里簡要介紹幾個常見屬性的Value結(jié)構(gòu):
MAPPED-ADDRESS
MAPPED-ADDRESS同時也是classic STUN的一個屬性缺虐,之所以還存在也是為了前向兼容。其包含了NAT客戶端的反射地址礁凡,F(xiàn)amily為IP類型高氮,即IPV4(0x01)或IPV6(0x02),Port為端口顷牌,Address為32位或128位的IP地址剪芍。注意高8位必須全部置零,
而且接收端必須要將其忽略掉窟蓝。

 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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0 0 0 0 0 0 0 0|    Family     |           Port                |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                 Address (32 bits or 128 bits)                 |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  

XOR-MAPPED-ADDRESS
XOR-MAPPED-ADDRESS和MAPPED-ADDRESS基本相同罪裹,不同點是反射地址部分經(jīng)過了一次異或(XOR)處理。對于X-Port字段运挫,是將NAT的映射端口以小端形式與magic cookie的高16位進行異或坊谁,再將結(jié)果轉(zhuǎn)換成大端形式而得到的,X-Address也是類似滑臊。之所以要經(jīng)過這么一次轉(zhuǎn)換,是因為在實踐中發(fā)現(xiàn)很多NAT會修改payload中自身公網(wǎng)IP的32位數(shù)據(jù)箍铲,從而導(dǎo)致NAT打洞失敗。

  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
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |x x x x x x x x|    Family     |         X-Port                |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                X-Address (Variable)
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  

ERROR-CODE
ERROR-CODE屬性用于error response報文中关划。其包含了300-699表示的錯誤代碼,以及一個UTF-8格式的文字出錯信息(Reason Phrase)贮折。

 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
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |           Reserved, should be 0         |Class|     Number    |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |      Reason Phrase (variable)                                ..
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  

另外,錯誤代碼在語義上還與SIP和HTTP協(xié)議保持一致资盅。比如:

  • 300:嘗試代替(Try Alternate)调榄,客戶端應(yīng)該使用該請求聯(lián)系一個代替的服務(wù)器。這個錯誤響應(yīng)僅在請求包括一個 USERNAME屬性和一個有效的MESSAGE-INTEGRITY屬性時發(fā)送每庆;否則它不會被發(fā)送,而是發(fā)送錯誤代碼為400的錯誤響應(yīng)缤灵;
  • 400:錯誤請求(Bad Request)伦籍,請求變形了,客戶端在修改先前的嘗試前不應(yīng)該重試該請求腮出。
  • 401:未授權(quán)(Unauthorized),請求未包括正確的資格來繼續(xù)胚嘲。客戶端應(yīng)該采用一個合適的資格來重試該請求慢逾。
  • 420:未知屬性(Unknown Attribute),服務(wù)器收到一個STUN包包含一個強制理解的屬性但是它不會理解口注。服務(wù)器必須將不認識的屬性放在錯誤響應(yīng)的UNKNOWN-ATTRIBUTE屬性中。
  • 438:過期Nonce(Stale Nonce)寝志,客戶端使用的Nonce不再有效,應(yīng)該使用響應(yīng)中提供的Nonce來重試材部。
  • 500:服務(wù)器錯誤(Server Error)唯竹,服務(wù)器遇到臨時錯誤乐导,客戶端應(yīng)該再次嘗試浸颓。

此外還有很多屬性,如USERNAME棵磷,NONCE,REALM仪媒,SOFTWARE等谢鹊,具體可以翻閱RFC3489算吩。

STUN 通信過程

1. 產(chǎn)生一個Request或Indication

當(dāng)產(chǎn)生一個Request或者Indication報文時,終端必須根據(jù)上文提到的規(guī)則來生成頭部冰抢,class字段必須是Request或者Indication艘狭,而method字段為Binding或者其他用戶拓展的方法挎扰。屬性部分選擇該方法所需要的對應(yīng)屬性巢音,比如在一些情景下我們會需要authenticaton屬性或FINGERPRINT屬性,注意在發(fā)送Request報文時候梧躺,需要加上SOFTWARE屬性(內(nèi)含軟件版本描述)。

2. 發(fā)送Requst或Indication

目前掠哥,STUN報文可以通過UDP秃诵,TCP以及TLS-over-TCP的方法發(fā)送续搀,其他方法在以后也會添加進來菠净。STUN的使用者必須指定其使用的傳輸協(xié)議,以及終端確定接收端IP地址和端口的方式牵咙,比如通過基于DNS的方法來確定服務(wù)器的IP和端口。
2.1 通過UDP發(fā)送
當(dāng)使用UDP協(xié)議運行STUN時洁桌,STUN的報文可能會由于網(wǎng)絡(luò)問題而丟失侯嘀×砹瑁可靠的STUN請求/響應(yīng)傳輸是通過客戶端重發(fā)request請求來實現(xiàn)的残拐,因此碟嘴,在UDP運行時,Indication報文是不可靠的娜扇。STUN客戶端通過RTO(Retransmission TimeOut)來決定是否重傳Requst栅组,并且在每次重傳后將RTO翻倍枢析。具體重傳時間的選取可以參考相關(guān)文章,如RFC2988醒叁。重傳直到接收到Response才停止,或者重傳次數(shù)到達指定次數(shù)Rc啊易,Rc應(yīng)該是可配置的,且默認值為7租谈。

2.2 通過TCP或者TCP-over-TLS發(fā)送
對于這種情景捆愁,客戶端打開對服務(wù)器的連接。在某些情況下昼丑,此TCP鏈接只傳輸STUN報文,而在其他拓展中矾克,在一個TCP鏈接里可能STUN報文和其他協(xié)議的報文會進行多路復(fù)用(Multiplexed)。數(shù)據(jù)傳輸?shù)目煽啃杂蒚CP協(xié)議本身來保證酒繁。值得一提的是,在一次TCP連接中州袒,STUN客戶端可能發(fā)起多個傳輸,有可能在前一個Request的Response還沒收到時就再次發(fā)送了一個新的Request郎哭,因此客戶端應(yīng)該保持TCP鏈接打開菇存,認所有STUN事務(wù)都已完成。

3. 接收STUN消息

當(dāng)STUN終端接收到一個STUN報文時依鸥,首先檢查報文的規(guī)則是否合法,即前兩位是否為0,magic cookie是否為0x2112A442絮供,報文長度是否正確以及對應(yīng)的方法是否支持照棋。如果消息類別為Success/Error Response萎馅,終端會檢測其事務(wù)ID是否與當(dāng)前正在處理的事務(wù)ID相同拱绑。如果使用了FINGERPRINT拓展的話還會檢查FINGERPRINT屬性是否正確霜幼。
完成身份認證檢查之后胀屿,STUN終端會接著檢查其余未知屬性塘揣。
3.1 處理Request
如果請求包含一個或者多個強制理解的未知屬性宿崭,接收端會返回error response,錯誤代碼420(ERROR-CODE屬性)葡兑,而且包含一個UNKNOWN-ATTRIBUTES屬性來告知發(fā)送方哪些強制理解的屬性是未知的。服務(wù)端接著檢查方法和其他指定要求吆鹤,如果所有檢查都成功洲守,則會產(chǎn)生一個Success Response給客戶端疑务。

?3.1.1 生成Success Response或Error Response</br>
?如果服務(wù)器通過某種驗證方法(authentication mechanism)通過了請求方的驗證梗醇,那么在響應(yīng)報文里最好也加上對應(yīng)的驗證屬性。
?服務(wù)器端也應(yīng)該加上指定方法所需要的屬性信息温鸽,另外協(xié)議建議服務(wù)器返回時也加上SOFTWARE屬性手负。
?對于Binding方法,除非特別指明竟终,一般不要求進行額外的檢查。當(dāng)生成Success Response時统捶,服務(wù)器在響應(yīng)里加上XOR-MAPPED-ADDRESS屬性敦姻。對于UDP歧杏,這是其源IP和端口信息迷守,對于TCP或TLS-over-TCP,這就是服務(wù)器端所看見的此次TCP連接的源IP和端口兑凿。

?3.1.2 發(fā)送Success Response或Error Response</br>
?發(fā)送響應(yīng)時候如果是用UDP協(xié)議,則發(fā)往其源IP和端口礼华,如果是TCP則直接用相同的TCP鏈接回發(fā)即可。

3.2 處理Indication
如果Indication報文包含未知的強制理解屬性祈惶,則此報文會被接收端忽略并丟棄扮匠。如果對Indication報文的檢查都沒有錯誤捧请,則服務(wù)端會進行相應(yīng)的處理棒搜,但是不會返回Response。對于Binding方法力麸,一般不需要額外的檢查或處理。收到信息的服務(wù)端僅需要刷新對應(yīng)NAT的端口綁定闺鲸。

由于Indication報文在用UDP協(xié)議傳輸時不會進行重傳陨舱,因此發(fā)送方也不需要處理重傳的情況。

3.3 處理Success Response
如果Success Response包含了未知的強制理解屬性游盲,則響應(yīng)會被忽略并且認為此次傳輸失敗∫娑校客戶端對報文進行檢查通過之后,就可以開始處理此次報文欣范。

以Binding方法為例,客戶端會檢查報文中是否包含XOR-MAPPED-ADDRESS屬性恼琼,然后是地址類型,如果是不支持的地址類型晴竞,則這個屬性會被忽略掉。

3.4 處理Error Response
如果Error Response包含了未知的強制理解屬性颤难,或者沒有包含ERROR-CODE屬性已维,則響應(yīng)會被忽略并且認為此次傳輸失敗。隨后客戶端會對驗證方法進行處理垛耳,這有可能會產(chǎn)生新的傳輸。
?到目前為止堂鲜,對錯誤響應(yīng)的處理主要基于ERROR-CODE屬性的值,并遵循如下規(guī)則:
?如果error code在300到399之間甫恩,客戶端被建議認為此次傳輸失敗酌予,除非用了ALTERNATE-SERVER拓展;
?如果error code在400到499之間抛虫,客戶端認為此次傳輸失敗雕欺;
?如果error code在500到599之間棉姐,客戶端可能會需要重傳請求屠列,并且必須限制重傳的次數(shù)伞矩。

任何其他的error code值都會導(dǎo)致客戶端認為此次傳輸失敗。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末苛让,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子狱杰,更是在濱河造成了極大的恐慌,老刑警劉巖宇色,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颁湖,死亡現(xiàn)場離奇詭異例隆,居然都是意外死亡,警方通過查閱死者的電腦和手機镀层,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門唱逢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人坞古,你說我怎么就攤上這事』痉悖” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵易阳,是天一觀的道長吃粒。 經(jīng)常有香客問我,道長徐勃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任很魂,我火速辦了婚禮檐涝,結(jié)果婚禮上法挨,老公的妹妹穿的比我還像新娘幅聘。我一直安慰自己,他們只是感情好帝蒿,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著暴氏,像睡著了一般绣张。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上侥涵,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機與錄音务豺,去河邊找鬼嗦明。 笑死笼沥,一個胖子當(dāng)著我的面吹牛娶牌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播乘凸,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼累榜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了壹罚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤赂蠢,失蹤者是張志新(化名)和其女友劉穎辨泳,沒想到半個月后玖院,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡难菌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年郊酒,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片燎窘。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡蹄咖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出比藻,到底是詐尸還是另有隱情倘屹,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布务蝠,位于F島的核電站烛缔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏践瓷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一喷舀、第九天 我趴在偏房一處隱蔽的房頂上張望淋肾。 院中可真熱鬧硫麻,春花似錦樊卓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奢赂。三九已至,卻和暖如春咱士,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背序厉。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工毕箍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人而柑。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像粹排,于是被迫代替她去往敵國和親涩澡。 傳聞我的和親對象是個殘疾皇子顽耳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容