计算机网络(第七版)习题4-13计算过程

网上计算机网络的习题答案不是复制黏贴就是排版糟糕,简直不是给人看的。今天做这题目花了不少时间,就顺便把计算过程记录下来,希望帮助到对这题有疑惑的人。

包含IP部分,首部长度正好为为5个4字节。

  1. 现将数据转换成二进制格式
1
2
3
4
5
0100 0101 0000 0000 0000 0000 0001 1100
0000 0000 0000 0001 0000 0000 0000 0000
0000 0100 0001 0001
0000 1010 0000 1100 0000 1110 0000 0101
0000 1100 0000 0110 0000 0111 0000 1001
  1. 计算 0100 0101 0000 0000 + 0000 0000 0001 1100
1
2
3
4
5
0100 0101 0000 0000
+
0000 0000 0001 1100
=
0100 0101 0001 1100
  1. 计算 0100 0101 0001 1100 + 0000 0000 0000 0001
1
2
3
4
5
0100 0101 0001 1100
+
0000 0000 0000 0001
=
0100 0101 0001 1101
  1. 计算 0100 0101 0001 1101 + 0000 0000 0000 0000
1
2
3
4
5
0100 0101 0001 1101
+
0000 0000 0000 0000
=
0100 0101 0001 1101
  1. 计算0100 0101 0001 1101 + 0000 0100 0001 0001
1
2
3
4
5
0100 0101 0001 1101
+
0000 0100 0001 0001
=
0100 1001 0010 1110
  1. 计算 0100 1001 0010 1110 + 0000 1010 0000 1100
1
2
3
4
5
0100 1001 0010 1110
+
0000 1010 0000 1100
=
0101 0011 0011 1010
  1. 计算 0101 0011 0011 1010 + 0000 1110 0000 0101
1
2
3
4
5
0101 0011 0011 1010
+
0000 1110 0000 0101
=
0110 0001 0011 1111
  1. 计算 0110 0001 0011 1111 + 0000 1100 0000 0110
1
2
3
4
5
0110 0001 0011 1111
+
0000 1100 0000 0110
=
0110 1101 0100 0101
  1. 计算 0110 1101 0100 0101 + 0000 0111 0000 1001
1
2
3
4
5
0110 1101 0100 0101
+
0000 0111 0000 1001
=
0111 0100 0100 1110
  1. 将上面的结果取反得出:
1
1000 1011 1011 0001

AWS Cloudformation 踩坑记录

最近用cloudformation时遇到了一些坑,在此记录一下。

Conditions变量无法直接当布尔类型使用

Conditions可以动态控制一些资源的创建:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Conditions: 
CreateProdResources: !Equals [ !Ref EnvType, prod ]
Resources:
EC2Instance:
Type: "AWS::EC2::Instance"
Properties:
ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", AMI]
MountPoint:
Type: "AWS::EC2::VolumeAttachment"
Condition: CreateProdResources
Properties:
InstanceId:
!Ref EC2Instance
VolumeId:
!Ref NewVolume
Device: /dev/sdh
NewVolume:
Type: "AWS::EC2::Volume"
Condition: CreateProdResources
Properties:
Size: 100
AvailabilityZone:
!GetAtt EC2Instance.AvailabilityZone

但是如果在其他地方像这样使用会报Unresolved resource dependencies CreateResources错误

1
2
3
4
5
6
7
8
/xxx/xx/xx.conf:
source:
!Sub https://${bucket}.s3.amazonaws.com/${prefix}/xx.conf
context:
create_resources: !Ref CreateResources
mode: "000644"
owner: root
group: root

解决办法就时将create_resources: !Ref CreateResources 改成 create_resources: !If [CreateResources, "true output ", "false output"]

aws-resource-init-files 传递布尔变量

AWS::CloudFormation::Init中 files属性可以用来创建文件,filescontext属性可以传递变量,来动态生成文件内容.
AWS文档里说文件是通过类似mustache的方式来处理的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
A typical Mustache template:

Hello {{name}}
You have just won {{value}} dollars!
{{#in_ca}}
Well, {{taxed_value}} dollars, after taxes.
{{/in_ca}}
Given the following hash:

{
"name": "Chris",
"value": 10000,
"taxed_value": 10000 - (10000 * 0.4),
"in_ca": true
}
Will produce the following:

Hello Chris
You have just won 10000 dollars!
Well, 6000.0 dollars, after taxes.

这里有个坑就是布尔类型在cloudformation里时当做字符类型来传递的,AWS官方认为这是一个feature而不是bug: What you have observed is a known behaviour with the CloudFormation servie
例如:

xxx.conf

1
2
3
4
5
6
7
{{#create_resources}}
this is true
{{/create_resources}}

{{^create_resources}}
this is false
{{/create_resources}}

yaml配置文件

1
2
3
4
5
6
7
8
9
/xxx.conf:
authentication: S3BucketAccess
source:
!Sub https://${bucket}.s3.amazonaws.com/${prefix}/xxx.conf
context:
create_resources: !If [CreateResources, true, false]
mode: "000644"
owner: root
group: root

这里无论 CreateResourcestrue 还是 false,文件内容始终会是 this is true,因为配置文件里的 truefalse 都被转成了字符类型。

这里的解决办法比较hack,就是将!If [CreateResources, true, false]改成!If [CreateResources, [1], []]:

1
2
3
4
5
6
7
8
9
/xxx.conf:
authentication: S3BucketAccess
source:
!Sub https://${bucket}.s3.amazonaws.com/${prefix}/xxx.conf
context:
create_resources: !If [CreateResources, [1], []]
mode: "000644"
owner: root
group: root

这里主要参考了 mustache 文档里 Inverted Sections : https://mustache.github.io/mustache.5.html

aws-resource-init 资源更新问题

aws-resource-init-sources可以用来下载压缩文件并解压到EC2指定目录,但这里有个问题就是如果目标文件夹已存在,cloudformation会将两文件夹内容合并而不是替换文件夹!比如AWS部署的项目使用的依赖LibraryA 1.0,将library升级到Library A 1.1并通过cloudformation source下载并解压新本版的项目到目标目录后,目标目录的项目文件夹里会同时存在Library A1.01.1版本。

解决办法也很简单,在用sources下载前将目标文件夹移除。

AWS平台的服务总有一些奇怪的限制或bug,调试时总会花不少时间,在此记录一下,希望能帮助到遇到相同问题的人,节约大家时间。

Update

  • 2019-07-07 添加aws-resource-init资源更新问题

Deskmini 310 黑苹果折腾记

家里的台机装了manjaro,用了一阵子感觉还是不顺手,加上苹果电脑是越来越贵了,所以有了弄一台黑苹果的想法。

期间看了不少有关黑苹果的资料,发现最简单的方法就是按照别人成功的硬件配置和EFI来安装,最终方案是按照 asrock_deskmini310_hackintosh 买的硬件:

型号 价格(RMB)
主板/机箱 H3101 969
CPU I7 8700 2299
内存 金士顿 DDR4 2666 16G 笔记本内存 x2 1228
SSD Intel 760p 512GB 579
无线/蓝牙 DW1560/BCM94352Z WIFI/Bluetooth module mini PCIE/NGFF M2 268
天线 NGFF M2无线网卡转接线天线 IPX4代转SMA线DeskMini华硕H110 X370 18
DP转VGA DP转VGA转换器 75

安装过程中走了不少弯路,这里记载一下:

  1. 由于我买来的主板BIOS版本是3.4版本的,直接安装会报一个nvme错误,想着升级一下BIOS能不能解决这问题,升级到4.1版本后发现还是有这错误,解决方案是要用clover configurator编辑下EFI文件,添加DSDT Patch
  2. 这个方案里视频是通过HDMI和DP接口输出的,家里的显示器是VGA接口,装到一半黑屏还以为是EFI文件有问题,最后还是接了电视机的HDMI完成的安装。显示器后来用的这款 绿联(UGREEN)DP转VGA转换器
  3. 按照tonymacx86上的教程来安装,第二次重启安装会报错,发现还是要先将EFI文件复制到安装镜像里才能安装成功,安装过程中可能会有panic错误,重启下再次安装就好了。
  4. 网卡和蓝牙买的是DW1560 BCM94352Z ,这里有一点要注意的是要买天线,不装天线的话会搜索不到蓝牙设备和WIFI
  5. 天线安装有点麻烦,我是把网卡拆下来才把天线接上去的

安装视频可以参考这个:

整个安装过程花了差不多七八个小时,不走弯路的话估计一两个小时就能搞定。

用了几天发现两个问题:

  1. 休眠和启动时音箱会有爆音
  2. 从休眠恢复会黑一下屏幕

2021-04-08 原来那位大佬改用外置显卡了,他的仓库还在用clover,并且好久没更新了,现在更换了免驱动的无线网卡BCM94360CS2,且改用了opencore引导,用的是这位大佬的配置文件appleserial/DeskMini

更新日志

  • 2019-06-16: 更新了发现的问题
  • 2019-08-07: 升级到了10.14.6一切正常
  • 2021-04-08: 更换成免驱动的无线网卡
  • 2024-03-18: 用hackintosh-club/ASRock-DeskMini-310将系统升级成了 Ventura

Mac OS配置Dnsmasq+Dnscrypt来解决DNS污染问题

天朝的网络是越来越糟糕了,前阵子访问amazon s3域名居然返回了127.0.0.1,与其时不时被域名污染,不如自己打一个dns服务器。

解决方案就是用Dnsmasq+DnscryptDnsmasq负责监听本地53端口,将国内域名解析转发到国内的dns服务器,国外域名解析请求转发到Dnscrypt监听的端口,Dnscrypt就收到的DNS解析请求转发到国外的DNS服务器。

安装

1
2
brew install dnsmasq
brew install dnscrypt-proxy

配置

Dnsmasq

编辑配置文件

1
2
3
4
5
vim /usr/local/etc/dnsmasq.conf

no-resolv
conf-dir=/usr/local/etc/dnsmasq.d
server=127.0.0.1#5300

dnsmasq会将DNS解析请求转发到dnscrypt监听的5300端口

域名文件

执行下面脚本将域名DNS信息保存到dnsmasq文件夹

1
2
3
4
5
#!/bin/sh

/usr/bin/curl -o /usr/local/etc/dnsmasq.d/accelerated-domains.china.conf https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf

/usr/bin/curl -o /usr/local/etc/dnsmasq.d/dnsmasq_gfwlist https://cokebar.github.io/gfwlist2dnsmasq/dnsmasq_gfwlist.conf

这里用的是电信的DNS服务器,如果你是联通的网络,你可以执行下面的脚本将配置文件中的DNS服务器换成联通的

1
sed -i -e 's/114.114.114.114/221.6.4.66/g' /usr/local/etc/dnsmasq.d/accelerated-domains.china.conf 

Dnscrypt

Dnscrypt配置 vim /usr/local/etc/dnscrypt-proxy.toml

1
2
3
listen_addresses = ['127.0.0.1:5300', '[::1]:5300']
fallback_resolver = '221.6.4.66:53'
server_names = ['google', 'cloudflare', 'cloudflare-ipv6']

这里本来想配5353端口的,但发现这个端口被chrome占用了。

启动服务

1
2
sudo brew services restart dnsmasq
sudo brew services restart dnscrypt-proxy

重启后将本机DNS指向127.0.0.1即可。

更新日志

2020-05-14: 修改了文章错误

Manjaro自动挂载samba文件夹

Manjaro从地址栏访问samba共享的方式总有点问题,会时不时提示没有文件夹修改权限。最近有时间研究了下,发现命令行挂载的方式比较靠谱。

由于路由器刷的是openwrt,软件源里安装的samba服务端版本似乎是比较老的版本,manjaro命令行挂载似乎用的是较新的samba协议,调了半天发现客户端这边要加下版本号。

挂载命令:

1
2
3
cd /mnt
sudo mkdir share0
sudo mount.cifs //192.168.1.1/share0 /mnt/share0 -o user=SAMBA_USERNAME,pass=SAMBA_PASSWORD,uid=1000,gid=1000,sec=ntlmssp,vers=1.0 --verbose

命令行挂载调通后,要实现开机自动挂载就容易的多了,官方文档提供的多种的挂载方式,这里以systemd为例:

  1. /etc/samba/下建立credentials文件夹:sudo mkdir credentials,创建比如名为share0的文件: sudo vim share0,内容如下:
1
2
username=your samba username
password=your samba password
  1. 创建systemd unit文件:sudo /etc/systemd/system/mnt-share0.mount,内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [Unit]
    Description=Mount Share at boot

    [Mount]
    What=//192.168.1.1/share0
    Where=/mnt/share0
    Options=x-systemd.automount,credentials=/etc/samba/credentials/share0,iocharset=utf8,uid=1000,gid=1000,sec=ntlmssp,vers=1.0,rw
    Type=cifs
    TimeoutSec=30
    ForceUnmount=true

    [Install]
    WantedBy=multi-user.target

    Note:这里有一点要注意的是你的挂载路径(where)必须与你的文件名(mnt-share0)对应,比如你挂载到/mnt/share, 那你的文件就必须为mnt-share0.mount

  2. 启用服务sudo systemctl enable mnt-share0.mount

  3. 启动服务sudo systemctl start mnt-share0.mount

到这里samba文件夹就能开机自动挂载,官方还提供了其他的自动挂载方式,详情可参考文档。

参考:

https://wiki.archlinux.org/index.php/samba#As_systemd_unit

Spring Boot连接MongoDB

最近在做的项目用到了Mongo DB,发现在开启用户认证的情况下,用URI的方式连接总是提示认证失败,只有在分别设置了username ,password , database等字段才能连接成功。

1
2
3
4
5
6
7
spring:
data:
mongodb:
authentication-database: ${MONGODB_AUTHENTICATION_DATABASE:admin}
username: ${MONGODB_USERNAME:username}
password: ${MONGODB_PASSWORD:password}
database: ${MONGODB_DATABASE:database}

之前一直认为Spring Boot连接Mongo DB的方式和连JDBC差不多,今天抽空研究了下,发现URI中的数据库名其实是存储用户认证信息的数据库,实际数据库要通过database设定:

1
2
3
4
5
spring:
data:
mongodb:
database: ${MONGODB_DATABASE:database}
uri: ${MONGODB_URI:mongodb://username:password@localhost:27017/authentication_database}

官方文档

/database

Optional. The name of the database to authenticate if the connection string includes authentication credentials in the form of username:password@. If /database is not specified and the connection string includes credentials, the driver will authenticate to the admin database. See also authSource.

AWS S3 'Permissions on the destination queue do not allow S3 to publish notifications from this bucket' 问题的解决方法

在AWS平台给S3配置发送存储事件到SQS时遇到了如下错误提示:

Unable to validate the following destination configurations. Permissions on the destination queue do not allow S3 to publish notifications from this bucket.

在IAM那里捣鼓了半天,给S3加上了SQS相关的权限后依然提示错误信息。 正当毫无头绪的时发现SQS有个Permission标签,在这里配置相关权限后就可以解决错误提示了。

Image

原来SQS默认是不接受发送过来的事件的,印象当中之前是不需要配置的,也不知道这功能是啥时候加上去的,感觉AWS的权限系统有时太复杂了。。。

Openwrt x86安装教程

网上Openwrt x86虚拟机安装的教程一大堆,却很少见到非虚拟机的教程,现在正好有机会重新刷机,就顺便把步骤记录一下,免得再次踩坑。

镜像下载

第一步就是下载openwrt x86的镜像,这里两个镜像可以选择,带squashfs的刷机后会有一个只读的分区,带ext4的所有分区都是可读写的。本教程是以combined-ex4为例子的。

下载地址:openwrt-18.06.2-x86-64-combined-ext4.img.gz

combined-squashfs 和 combined-ex4 的区别:

combined-squashfs.img.gz This disk image uses the traditional OpenWrt layout, a squashfs read-only root filesystem and a read-write partition where settings and packages you install are stored. Due to how this image is assembled, you will have only 230-ish MB of space to store additional packages and configuration, and Extroot does not work.

combined-ext4.img.gz This disk image uses a single read-write ext4 partition with no read-only squashfs root filesystem, which allows to enlarge the partition. Features like Failsafe Mode or Factory Reset won’t be available as they need a read-only squashfs partition to function.

制作linux启动盘

我们需要两个U盘,其中一个就是用来做linux启动盘,这里以SystemRescueCd为例,制作USB启动盘的教程可一参考这里:Installing-SystemRescueCd-on-a-USB-stick/

USB启动盘制作好后,将下载下来的openwrt安装包拷贝到另一个U盘。

安装镜像

将两个U盘插入软路由,以linux启动盘启动,成功进入系统后执行以下命令将第二个U盘挂载到系统里:

1
2
mkdir /mnt/usb
mount /dev/sdx /mnt/usb

解压并将镜像刷到软路由内存里:

1
2
3
cd /mnt/usb
gunzip openwrt-18.06.2-x86-64-combined-ext4.img.gz
dd if=openwrt-18.06.2-x86-64-combined-ext4.img of=/dev/sdX

其中sdx就是你软路由的安装盘。

PS:官网里的步骤并没有提到解压这一步骤,实际操作中直接dd的话,openwrt是无法启动的,可能是linux系统的差异。

分区扩容(可选)

刷入openwrt后,执行fdisk -l,就会看到软路由的sdx盘被分成了两个分区,你会发现第二个分区只有256M,这里就可以调节第二个分区的大小,将硬盘的剩余容量全部划分到第二个分区:

  1. fdisk -l /dev/sdx将第二个分区的起始扇区号start的值记下来
  2. fdisk /dev/sdx 进入修改硬盘分区信息
  3. 输入d,然后回车
  4. 这里会提示你要删除哪个分区,输入2,然后回车
  5. 输入n,然后回车,选择分区类型primaryextended都可以。
  6. 选择分区后会让你输入分区开始扇区号,这里输入之前记下来的扇区号
  7. 输入w,这时候会提示你Partition #2 contains a ext4 signature. Do you want to remove the signature?这一步很重要,这里要选no
  8. 输入w,然后回车
  9. 分区完成后执行resize2fs /dev/sdx2,分区扩容就大功告成了。

系统配置

  • 重启进入Openwrt系统后,系统会开放一个lan口,将网线接入这个lan口后就可以通过192.168.1.1来访问路由器管理界面了。
  • 进入管理界面后需要设置管理员密码,同时你可以上传ssh key,免得每次ssh都需要输入密码。
  • interfaces页面,LAN标签页面,在Physical settings->Interface你可以修改路由的lan口,将另外几个没开放的lan口都勾选。
  • WAN标签页面,Protocol选择PPPoE,输入宽带密码,save and apply就可以上网了。

应用安装

我们会安装一些应用,但这里有个坑就是应用的安装源是http的,可能会被劫持,所以要修改成https的。先执行以下命令,安装必备的包:

1
2
3
4
opkg update
opkg install ca-certificates ca-bundle
opkg install libustream-mbedtls
opkg install git-http curl

修改源为https

1
2
3
4
5
//将http改为https
vim /etc/opkg/distfeeds.conf
opkg update
//安装一些调试用的软件
opkg install bind-dig

一些常见问题

  1. Samba添加用户与设置密码

    1
    2
    vi /etc/passwd
    smbpasswd -a samba
  2. dnsmasqdnsmasq-full的区别

    dnsmasq-full多了ipset功能

  3. dnsmqsq --no-resolv

    1
    2
    --no-resolv
    Don't read /etc/resolv.conf. Get upstream servers only from the command line or the dnsmasq configuration file.
  4. ss-tunnel dns解析不了

一般原因有以下几点:

1. `ss-tunnel` 未加上`-u`参数,开启`udn relay`

2. `ss-server` 未加上`-u`参数,开启`udn relay`

3. 服务端未开启端口

调试用的命令:

1
2
3
4
5
6
7
//dnstracer
dnstracer -vo -s 127.0.0.1 google.com

//dns测试
dig +trace google.com
// dns请求也可以直接发送给ss-tunnel
dig google.com @127.0.0.1 -p 5353
  1. 开启ss-rules后域名无法解析

具体什么原因不是很清楚,可能是iptablesudp转发有点问题,ss-redir for UDP这项打勾去掉即可。

一些定时任务脚本

写了一些定时任务脚本,这里记录一下。

安全设置

Luci页面访问控制

Openwrt的管理页面默认是允许任何IP访问的,如果你的路由器有公网IP的话,那任何人都可访问到你家的路由器登录页面,通过下面设置只允许来自内网地址的访问:

修改配置文件:

1
vi /etc/config/uhttpd

192.168.1.1fd54:274c:96dd::1换成路由器的v4和v6地址,路由器的lan IP可以在Network-> Interfaces->LAN查看,openwrt默认情况下是192.168.1.1

1
2
3
4
5
6
7
# HTTP listen addresses, multiple allowed
list listen_http 192.168.1.1:80
list listen_http [fd54:274c:96dd::1]:80

# HTTPS listen addresses, multiple allowed
list listen_https 192.168.1.1:443
list listen_https [fd54:274c:96dd::1]:443

Note: 如果要访问通过IPv6访问界面,URL应该是这个样子的:http://[fd54:274c:96dd::1]

修改完成后重启服务:/etc/init.d/uhttpd restart

SSH 访问控制

登录openwrt管理页面 System -> Administration->Dropbear Instance

Interface 那一项选择lan,然后Save & Apply,这样你的路由器ssh只能通过内网访问了。

参考

更新日志

  • 2019-11-09 添加了安全设置

hexo-deploy-git提交历史丢失的解决方法

迫于笔记本太重再加上每天上下班要背两小时多,笔记本就一直丢在公司里了。家里的windows越用越不爽,装了ubuntu折腾了一阵子发现不是太好用,V站好多推荐manjaro linux,用下来很顺手而且非常稳定,以后家中主力操作系统就用manjaro了。

由于之前一直是在笔记本上写博客的,最近在manjaro上写博客提交后发现github pages的提交历史全丢了,一查下来是hexo-deployer-git这个插件搞的鬼,该插件第一次提交时会force push,覆盖仓库代码,插件作者似乎无意修复这个BUG,遂想弃用这插件。

网上查下来发现用travis ci来部署github pages是个不错的解决方法,而且这样的话不用每次都手动生成page和提交了。

实现方法也很简单,在项目里加上.travis.yml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
language: node_js

node_js:
- 11.10.0

cache: npm

script:
- ./node_modules/hexo/bin/hexo generate

deploy:
provider: pages
skip-cleanup: true
keep-history: true
github-token: $GITHUB_TOKEN
local-dir: public
repo: wancaibida/blog
target-branch: master
on:
branch: master

notifications:
email:
recipients:
- wancaibida@gmail.com
on_success: always

设置下github pages的仓库名称,在github上创建一个权限为public_repo 的token给travis用就好了。