《TCP/IP协议族(第4版)》读书笔记三

地址解析协议ARP

物理这一级,主机和路由器是用物理地址来区别的。物理地址是一个本地地址,管辖范围是本地网络,所以在本地范围内必须唯一。称为物理地址是因为通常(并非总是)在硬件上实现。一个具体实例是以太网协议中48位的MAC地址,被写入安装在主机或路由器中的网络接口卡(NIC)中。

一个分组交付到主机或路由器需要两级地址:逻辑地址和物理地址。需要将两者相互映射,方法是静态映射或动态映射。

静态映射就是创建一张表将逻辑地址和物理地址都记录,并存储在网络中的每一台机器中。局限显而易见。

动态映射是每次只要机器知道另一台机器的逻辑地址,就可以按照协议找出与之对应的物理地址。地址解析协议ARP是将逻辑地址映射为物理地址。逆地址解析协议RARP是将物理地址映射为逻辑地址,目前已被另一个协议取代。

1. ARP原理

当主机或路由器需要找出另外一个主机或路由器的物理地址时,就可以发送一个ARP查询分组,分组中包括了发送方的物理地址和IP地址以及接收方的IP地址。因为发送方不知道接收方的物理地址,所以需要在网络上广播该分组。

网络上的每一个机器都会接收并处理该分组,但只有与接收方IP地址相匹配的机器才会返回一个ARP响应分组,分组中包含有接收方的IP地址和物理地址,这个分组因为知道了对方的物理地址,所以只需要单播即可。

总体需要7个步骤:
1.发送方知道目标的IP地址。
2.IP请求ARP创建一个ARP请求报文,填入发送方的物理地址、IP地址和目标IP地址,而目标物理地址字段全填0(各字段详情见下)。
3.递交给数据链路层,封装成帧后,以发送方的物理地址作为源地址,以物理广播地址作为目的地址。
4.每个主机或路由器均会接收并处理(因为是广播地址),除了目标机器外,其余均会将这个分组丢弃。
5.目标机器用ARP回答报文进行回答,报文中包含它的物理地址,使用单播方式。
6.发送方接收到这个应答。
7.携带有给目标机器数据的IP数据报现在可以封装成帧,并用单播方式发送到终点。

2. 分组格式

FullSizeRender 3.jpg

硬件类型:16bit,定义运行ARP的物理网络类型。如以太网是1,ARP可用在任何物理网络上。

协议类型:16bit,定义使用的协议。如IPv4是0x0800,ARP可用于任何高层协议。

硬件长度:8bit,定义物理地址的长度,以byte为单位。如以太网是48bit=6byte。

协议长度:8bit,定义逻辑地址的长度,以byte为单位。如IPv4是4.

操作:16bit,定义分组类型。ARP请求是1,ARP回复是2.

发送方硬件地址可变长度字段,定义发送方的物理地址。如以太网是6byte。

发送方协议地址可变长度字段,定义发送方的逻辑地址。对于IPv4是4byte。

目标硬件地址可变长度字段,定义接收方的物理地址。如以太网是6byte。对于ARP请求报文,此字段为全0,因为发送时并不知道接收方的物理地址。

目标协议地址可变长度字段,定义接收方的逻辑地址。对于IPv4是4byte。

ARP分组直接封装在物理链路帧中,帧中的类型字段会指出此帧携带的数据是ARP分组。

3. 代理ARP

代理ARP(proxy ARP)技术,可用于产生一种子网划分的效果。代理ARP是代表了一组主机的ARP。当运行代理ARP的路由器收到一个ARP请求后,希望找出这些主机中的某一台主机的物理地址时,此路由器就会返回它自己的物理地址的ARP回答分组。当这个路由器收到真正的数据IP分组后,会把这些分组发送给响应的主机或路由器。

4. ARP软件构成

FullSizeRender 4.jpg

高速缓存表:当主机或路由器接收到一个IP数据报,会把相应的物理地址存储在高速缓存表中。这样同样目的地的数据报可以重复利用一个物理地址,提高效率,但是由于空间有限,并不会无限制时间存储。
每个表项包含以下字段:
1.状态,显示表项的状态,FREE/PENDING/RESOLVED。分别代表生存时间到期,可分配给新表项;表项的ARP请求已发出但未收到回复;表项映射已建立,此表项信息可以被使用。
2.硬件类型
3.协议类型
4.硬件长度
5.协议长度:以上三项与ARP分组中对应字段相同。
6.接口号:指代路由器(或连接多个网络的主机)的不同连接所对应的接口号。
7.队列号:ARP使用带编号的队列将等待地址解析的分组进行排队,发往同一个终点的分组通常放在同一个队列中。
8.尝试:已发送多少次ARP请求。
9.超时:剩余的生存时间,单位为秒。
10.硬件地址:对端物理地址,接收到ARP回复报文时才填入数据,否则为空。
11.协议地址:对端IP地址。

队列:ARP使用带编号的队列将等待地址解析的分组进行排队,发往同一个终点的分组通常放在同一个队列中。输出模块把未解析的分组发送到相应的队列。输入模块从队列中取出分组,并连同解析出的物理地址发送给数据链路层传输。

输出模块:等待来自IP的分组。接收到后,检查高速缓存表,查找是否有表项对应该分组的目的IP地址。
若找到了,并且状态是RESOLVED,则将分组连同目的硬件地址一起传递给数据链路层。
若找到了,并且状态是PENDING,则将分组相应的队列中等待。
若找不到,输出模块新建一个队列,将分组放入队列中。并为这个终点在高速缓存表中创建一个表项,把“尝试”字段置为1,并发送ARP广播请求分组。

输入模块:等待ARP分组(请求或回答)到达。接收到后,检查高速缓存表,查找是否有表项对应该分组的目的IP地址。
若找到了,并且状态是PENDING,则模块对该表项进行更新,即把物理地址写入,并把状态更改为RESOLVED。还要设置超时时间值。然后将对应的队列中的分组逐个取出,连同物理地址发送给数据链路层传输。
若找到了,并且状态是RESOLVED,还是要更新该表项,这是因为目的地硬件地址可能已改变,超时时间值也要重置。
若找不到,则创建一个新表项。协议要求任何收到的信息都要添加到表中以供以后使用,此时状态为RESOLVED。超时时间值也要设置。
最后,还要查看下到达的ARP分组是不是请求分组,若需要回复,则创建一个ARP回答分组并发送给对方。具体是更改请求分组中的“操作字段”从请求变为回答,并填入目标硬件地址。

高速缓存控制模块:负责维护高速缓存表。周期性地逐项检查高速缓存表。
若为FREE则跳过。
若为PENDING,则将尝试字段+1,再检查尝试字段,若超过最大尝试次数,则改状态为FREE,并销毁相应队列,还要向最初数据源发送一个ICMP报文,若小于,则发送一个ARP请求分组。
若为RESOLVED,则把超时字段减去自上次检查以来经过的时间,若此时数值小于等于0,则状态变为FREE,并销毁相应队列。

网际控制报文协议ICMP

网际控制报文协议ICMPv4为了补偿IP协议缺少差错控制和缺少辅助机制这两个缺点而设计。

常见差错报告场景:路由器找不到可到达最后终点的路由器,或生存时间字段值为0必须丢弃数据报,最终目的主机在时间内未收到一个数据报的所有分组必须全部丢弃时。

常见辅助场景:主机需要判断某个路由器或者对方主机是否活跃,网络管理员需要来自其他主机或路由器的信息。

ICMP属于网络层,但是它的报文是要首先封装成IP数据报,再传递给下一层。IPv4报头中的协议字段值为1时,表示携带的是数据是ICMP报文。

1. 报文

ICMP报文可分为两类:差错报告报文,报告了路由器或主机在处理IP数据报时可能遇到的问题;查询报文,成双成对出现,帮助主机或网络管理员从某个路由器或对方主机那里获取特定的信息。

FullSizeRender 6.jpg

报文由一个8byte首部和可变长的数据部分组成。类型字段8bit,是ICMP的类型,定义了报文类型。代码字段8bit,指明发送原因。校验和,16bit,和IP的校验和一样,使用反码。首部的其余部分,32bit,对于每种类型的报文都是特有的。

在差错报文中,数据部分携带的是用于找出引起差错的原始分组的信息。在查询报文中,数据部分携带的是基于查询类型的额外信息。

FullSizeRender 5.jpg

1.1 差错报告报文

ICMP并不能纠错,只是简单地报告差错。差错报文总是发送给最初的数据源,因为在数据报中关于路由唯一可用的信息就是源IP地址和目的IP地址。IMCP利用了源IP地址把差错报文发送给数据报的源点。

分为5类:终点不可达、源点抑制、超时、参数问题、改变路由。

特殊注意点:携带ICMP差错报文的数据报,不再产生ICMP差错报文。对于分片的数据报,若不是第一个分片,不产生ICMP差错报文。具有多播地址的数据报,不产生。具有特殊地址(如127.0.0.0或0.0.0.0)的数据报,不产生。

差错报文的数据部分包括原始数据报的IP首部,加上该数据报的前8byte。前者是为了向接受差错报文的原始源点给出关于数据报本身的信息。后者是因为8byte提供了关于端口号(UDP和TCP)的信息,为了让源点通知这些协议就需要这些信息。
所以ICMP的差错报文是ICMP首部+原IP首部+源IP数据头8byte。当ICMP要发送时,还要在前面加一个新IP首部。

终点不可达:当路由器无法为一个数据报找到路由,或者主机无法交付一个数据报,此数据报被丢弃,需要向源主机返回一个重点不可达报文。

首部的类型字段为3,代码字段指明了丢弃的原因。首部的其余部分未使用,为全0。

为0:网络不可达,知道目的网络的存在却无法到达,可能是硬件故障。
为1:主机不可达,知道目的主机的存在却无法到达,也可能是硬件故障。
为2:协议不可达,目的主机收到IP报文后,发现其中携带的高层协议并未运行。
为3:端口不可达,数据报要交付的目标应用程序(进程)未运行。
为4:需要分片,但DF(不分片)已设置。
为5:源路由不能完成,即源路由选项中定义的一个或多个路由器无法通过。
为6:目的网络未知,路由器根本没有关于这个网络的信息。
为7:目的主机未知,路由器根本不知道目的地主机的存在。
为8:源主机被隔离了。
为9:从管理上禁止与目的网络通信。
为10:从管理上禁止与目的主机通信。
为11:对指明的服务类型,网络不可达。
为12:对指明的服务类型,主机不可达。
为13:主机不可达,因为管理员已经在这个主机上放置了过滤器。
为14:主机不可达,因为主机违反了优先级策略,这种报文由路由器发出,指出所要求的优先级在该目的主机是不允许的。
为15:主机不可达,因为它的优先级被截止,当网络操作员为网络的操作设定了最小的优先级限制,但发送的数据报的优先级小于此限制。
以上2或3的报文只能由目的主机产生,其余几个报文只能由路由器产生。

当然,以上并没有包括所有终点不可达的情况。

源点抑制:由于IP无连接,产生数据报的源点,和转发数据报的路由器以及目的点间没有任何通信联系,故缺乏流量控制和拥塞控制。

当路由器或主机因拥塞而丢弃数据报时,它就向该数据包的发送方发送一个源点抑制报文。有两个作用:通知源点,数据报已被丢弃;警告源点,路径中的某处出现拥塞,源点必须放慢发送过程。

首部的类型字段为4,代码字段为全0,首部其余部分也为全0。

几点补充:
遭受拥塞的路由器必须为每一个丢弃的报文都发送一个源点抑制报文。
没有机制告诉源点拥塞已缓解,源点只能不停降低发送速率知道不再收到源点抑制报文。
在一对一的通信中,源点抑制报文很有用。而在多对一的通信中,路由器或目的主机不知道哪一个源点应该为拥塞负责,可能丢弃了来自低速率的源点的数据报,而没有丢弃来自高速率源点的数据报,此时源点抑制报文就不一定有用了。

超时:数据报中的超时字段为0时,需要丢弃,此时路由器要向源点发送一个超时报文。
当一个报文的所有分片未能在规定时间内全部到达目标主机时,也要产生超时报文。当第一个分片到达时,目标主机就开始计时。

首部的类型字段为11,代码字段为0或1(分别指代以上两种情况),首部的其余部分为全0。

参数问题:数据报的首部中出现二义性,或发现某字段缺少值,就回丢弃数据报,并返回一个参数问题报文。

首部的类型字段为2,代码字段为0或1:0代表首部的某个字段中有差错或二义性,指针字段(在首部的其余部分中)要指向有问题的字段,1代表缺少的选项部分,此时不适用指针。首部的其余部分若未被使用,则全为0。

改变路由:在网络中,路由器的路由表通常是动态变化的,而主机的路由表通常使用静态路由选择。因此主机有可能会把另一个网络的数据报发送给一个错误的路由器(没有与时俱进)。此时,收到这个数据报的路由器会将数据报转发给正确的路由器,但是为了更新主机中的路由表,路由器还要向主机发送一个改变路由报文。

主机在刚开始工作时只有一张很小的路由表,这个路由表逐渐增大和更新。完成这项任务的工具之一就是改变路由报文。

首部的类型字段为5,代码为0~3,首部的其余部分是合适的路由器的IP地址。

需要注意的是,此种情况下路由器不会丢弃报文。

代码字段缩小了改变路由的范围:
为0,对特定网络路由的改变。
为1,对特定主机路由的改变。
为2,基于制定服务类型的对特定网络路由的改变。
为3,基于制定服务类型的对特定主机路由的改变。

1.2 查询报文

查询报文是成双成对的,起初设计了5对,但其中3对已过时。还在使用的是回答请求与回答,时间戳请求与回答。使用此类ICMP报文时,先由一个节点先发送一个报文,再由目的节点以指明的格式进行回答。

回送请求与回答:回送请求与回送回答报文是为了诊断而设计的。组合起来可确定双方是否可以通信。此外还证明了中间的路由器也能够接收、处理和转发数据报。

通常会调用分组因特网搜寻器(ping)命令来检查另一个主机是否可达。它会提供一串信息以供统计使用。

首部的类型字段为8或0,8是回送请求,0是回送回答。代码字段是0。首部的其余部分分为两部分,16bit的标识符,通常与发起请求的进程的ID是一致的,16bit的序号,通常是一个序列号。

在报文的数据部分,回送回答报文中必须copy回送请求中的数据部分,要一模一样。

时间戳请求和回答:来确定IP数据报在这两个机器之间来回所需的往返时间。也可用来同步时间。

首部的类型字段为13或14,13是时间戳请求,14是时间按此回答。代码字段是0。首部的其余部分和回送请求与回答一致。

数据部分是3个时间戳,每个32bit,分别是原始时间戳,接收时间戳,发送时间戳,都要保存一个数,代表以通用时间(以前称为格林威治时间)的午夜起测量出的时间,单位是毫秒。

源点生成时间戳请求报文,并把它的发送时间填入原始时间戳,其他字段置0。
终点生成时间戳回答报文,原始时间戳copy即可,接收时间戳填入接收时间,发送时将发送时间戳填入。
源点接收到时间戳回答报文后,进行计算:
发送时间 = 接收时间戳 - 原始时间戳
接收时间 = 分组返回的时间 - 发送时间戳
往返时间 = 发送时间 + 接收时间

当双方时间同步时,计算结果才是精确的。但是未同步时,由于每一个时钟在往返时间的计算中出现了2次,差别抵消,也还是准确的。

若给出实际的单项时间,则可进行双方间的时间同步:
时间差 = 接收时间戳 - (原始时间戳 + 单向经历时间)

将往返时间除2可得到准确的单向经历时间。

过时的报文:信息请求和回答报文,它们的任务移交给地址解析协议ARP。地址掩码请求和回答,移交给动态主机配置协议DHCP。路由器询问和通告报文,移交给动态主机配置协议DHCP。

2. 排错工具

ping,查出某个主机是否已加电并能够响应。见我之前的笔记:[记录]Ping命令粗略

traceroute跟踪一个分组从源点到终点的路径。这个应用级的程序使用UDP服务,巧妙地使用了两个ICMP报文——超时报文和终点不可达报文来找出一个分组的路由。主要使用ICMP报文和IP分组中的TTL(生存时间)字段。

举例,主机A到主机B间需要依次通过路由器R1和R2。
首先,主机A要找到路由器R1的地址和分组在它们之间的往返时间,这个过程会重复3次,以得到一个较为准确的往返时间平均值。a). 主机A的traceroute使用UDP向终点B发送一个分组,被封装成IP分组,且TTL值为1,并记下发送时间。b). 路由器R1收到该分组,TTL减一变为0,R1丢弃该分组并向主机A发送ICMP超时报文。c). 主机A收到ICMP报文,利用IP的源地址找出R1地址,并记下分组的到达时间。与a)中的时间差即为往返时间。

然后,主机A重复以上步骤来找出R2的地址,此次TTL为2,因此R1会转发分组,而R2会丢弃并发送ICMP超时报文。

最后,分组的TTL设为3,但主机B接收到该分组后并不会丢弃该分组,因为已经到达终点B。traceroute使用一种策略,UDP的目的端口被设置成UDP协议不支持的一个端口,这样当主机B收到该分组后,会因为找不到可以接收交付的程序而丢弃该分组,并向主机A发送一个ICMP终点不可达报文。因为路由器不会检查UDP首部,所以不会在R1和R2处被检查出来而丢弃。主机A收到ICMP报文后,因为终点已找出,不会再发送更多分组。

3. ICMP软件构成

由输入模块和输出模块组成,前者处理到来的ICMP分组,后者处理对ICMP服务的请求。

输入模块:当一个来自IP层的ICMP分组要交付给它时,就被激活。若收到的是请求报文,则输入模块产生回答报文并发送。若收到的是改变路由报文,则更新路由表。若收到的是差错报文,则通知相关协议有关差错的情况。

输出模块:根据高层协议或IP协议的要求来创建请求报文、询问报文或差错报文。若来自IP,则输出模块必须检查是否合理,有四种情况不允许创建ICMP报文:携带ICMP差错报文的IP分组、被分片的IP分组、多播IP分组、IP地址为0.0.0.0或127.X.Y.Z的IP分组。

移动IP

1. 编址

使用IP协议提供移动通信时必须解决的主要问题是编址。

最初的的IP编址的假设:主机是固定的,并且连接到某个特定的网络。所以IP地址由两部分组成:前缀(网络地址)+后缀(主机地址)。暗示因特网上的主机无法携带一个IP地址从一个地方到其他地方而保持不变。只有连接到对应的网络上,这个地址才是有效的,如果网络改变了,则之前的地址就无效了。

对于移动主机,有几种解决方案。

改变地址:移动到新的网络时改变它的地址,使用DHCP来获得新地址。缺点:配置文件可能改变;移动到新网络后,主机需要重启;DNS表必须更新,以使因特网上的其他主机都知道变化;移动过程中,数据传输会中断,因为客户端和服务器端在传输时IP地址和端口号需要保持不变。

两个地址:原始地址称为归属地址,临时地址称为转交地址。前者使得主机和它的归属网络相关联,后者与移动到的新网络相关联。

2. 代理

当移动主机接入一个外地网络时,它就会在代理发现阶段和登记阶段收到自己的转交地址。

需要一个归属代理和外地代理。
归属代理通常是连接在移动主机的归属网络上的路由器,当远程主机向移动主机发送数据时,归属代理就充当该移动主机。接收后,再把分组转交给外地代理。
外地代理通常是连接在外地网络上的路由器,接收归属代理发送过来的分组,并转交给移动主机。移动主机也可以充当外地代理,此时必须能够收到自己的转交地址,通常是用DHCP来实现。

3. 三个阶段

要与远程主机通信,有三个阶段:代理发现、登记、数据传送。

代理发现:移动主机在离开归属网络之前发现归属代理,掌握归属代理的地址;在移动到外地网络后发现外地代理。

当一个路由器充当代理的角色,则可使用ICMP的路由器通告分组,在后面附带代理通告报文来实现代理通告

当移动主机移动到新网络但没收到代理通告时,可使用ICMP询问报文通知代理,让代理知道它的需求,即为一个代理询问

登记:移动主机向外地代理登记;外地代理以移动主机的身份来向归属代理登记;截止期到了后移动主机必须更新登记;移动主机回归归属网络后必须取消登记。

登记请求或回答使用UDP,代理使用端口是434。

数据传送:分为四个步骤。

1.从远程主机到归属代理。远程主机发送分组时还以为移动主机在归属网络,分组被归属代理截获,使用了代理ARP技术。

2.从归属代理到外地代理。使用隧道技术,将分组发送给外地代理。归属代理将原IP分组封装在另一个IP分组中。

3.从外地代理到移动主机。从大IP分组中取出原IP分组,并查询登记表,找到转交地址,并发送。

4.从移动主机到远程主机。正常发送,使用归属地址作为源地址。

移动主机对于因特网的其余部分是不可知的,远程主机发送时使用的目的地址,以及收到的分组中的源地址,都是移动主机的归属地址,所以不可知。

4. 低效率

很严重的情况成为两次穿越或2X。中等严重的情况成为三角路由选择或狗腿路由选择。

两次穿越:移动主机与远程主机处于同一网络。移动主机到远程主机不存在低效问题,而远程主机到移动主机通信时,却需要穿越互联网两次,造成低效。

三角路由选择:低效情况较轻,此种情况下移动主机和远程主机没有连接在一个网络上。移动主机到远程主机不存在低效问题,而远程主机到移动主机通信时,需要先到归属代理,再由外地代理找到移动主机,相当于三角形的两边,而不只是一条边。

一种解决方案是,当归属代理收到第一个来自远程主机的分组时,进行转发的同时,向远程主机发送一个更新绑定分组,使之在以后发送给该移动主机时选择这个转交地址,远程主机会将此信息存入高速缓存中。引入的问题是,一旦移动主机又移动,则高速缓存的信息会过时,这种情况下,归属代理需要向远程主机发送告警分组以通知改变。

参考

《TCP/IP协议族(第4版)》 (Behrouz A.Forouzan) 第八、九、十章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容