X11 is designed as client-server mode. The communication between the X client and server complies with TCP protocol. Recently I have a Windows X server VcXsrv installed on my Windows 10 and I debug an OpenGL demo glxgears on the WSL2 with tcpdump.
Environment
WSL2 is equipped with its own networking interface like a virtual machine.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $ ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.28.233.193 netmask 255.255.240.0 broadcast 172.28.239.255 inet6 fe80::215:5dff:fe27:9562 prefixlen 64 scopeid 0x20<link > ether 00:15:5d:27:95:62 txqueuelen 1000 (Ethernet) RX packets 221579 bytes 15160108 (15.1 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 306691 bytes 15714800233 (15.7 GB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 392 bytes 43340 (43.3 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 392 bytes 43340 (43.3 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
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 27 28 29 30 $ /mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -C "ipconfig" Windows IP Configuration Ethernet adapter vEthernet (WSL): Connection-specific DNS Suffix . : Link-local IPv6 Address . . . . . : fe80::412b:ad3:5548:67ba%38 IPv4 Address. . . . . . . . . . . : 172.28.224.1 Subnet Mask . . . . . . . . . . . : 255.255.240.0 Default Gateway . . . . . . . . . : Wireless LAN adapter ±¾µØÁ¬½Ó* 1: Media State . . . . . . . . . . . : Media disconnected Connection-specific DNS Suffix . : Wireless LAN adapter ±¾µØÁ¬½Ó* 10: Media State . . . . . . . . . . . : Media disconnected Connection-specific DNS Suffix . : Wireless LAN adapter WLAN: Connection-specific DNS Suffix . : DHCP HOST Link-local IPv6 Address . . . . . : fe80::954b:e66f:4065:20af%20 IPv4 Address. . . . . . . . . . . : 192.168.2.100 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . : 192.168.2.1
After starting up the X server VcXsrv, you need to export the environmnet variable DISPLAY
on the WSL. In case of the vEthernet configuration changed after rebooting you’d better do it like this:
1 export DISPLAY=$(grep 'nameserver' /etc/resolv.conf | awk '{print $2}' ):0
NOTE: The Firewall between the host and WSL2 must be disabled or your X client can not connect VcXsrv.
Debugging
I trace the demo glxgears using gdb and tcpdump at the same time.
1 sudo tcpdump -vvX not icmp and not arp and not udp and portrange 37900-37999 -w x110224.pcap
vv: verboser than -v
X: show the packet’s content
not icmp: filter out icmp packets
not arp: filter out arp packets
not udp: filter out udp packets
portrange 37900-37999: listening on the ports from 37900 to 37999
w x110224.pcap: save the packet captures into the file
1 tcpdump -X -r x110224.pcap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 reading from file /home/luc/github/x110224.pcap, link-type EN10MB (Ethernet) 09:11:56.659816 IP 172.28.233.193.37950 > 172.28.224.1.x11: Flags [P.], seq 2796598646:2796598658, ack 1053772981, win 259, length 12 0x0000: 4500 0034 1d84 4000 4006 fb43 ac1c e9c1 E..4..@.@..C.... 0x0010: ac1c e001 943e 1770 a6b0 b576 3ecf 4cb5 .....>.p...v>.L. 0x0020: 5018 0103 2223 0000 6200 0300 0400 0000 P..."#..b....... 0x0030: 4452 4932 DRI2 09:11:56.660218 IP 172.28.224.1.x11 > 172.28.233.193.37950: Flags [P.], seq 1:33, ack 12, win 8211, length 32 0x0000: 4500 0048 d9d7 4000 8006 fedb ac1c e001 E..H..@......... 0x0010: ac1c e9c1 1770 943e 3ecf 4cb5 a6b0 b582 .....p.>>.L..... 0x0020: 5018 2013 cf36 0000 0100 0a00 0000 0000 P....6.......... 0x0030: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0x0040: 0000 0000 0000 0000 ........ 09:11:56.660232 IP 172.28.233.193.37950 > 172.28.224.1.x11: Flags [.], ack 33, win 259, length 0 0x0000: 4500 0028 1d85 4000 4006 fb4e ac1c e9c1 E..(..@.@..N.... 0x0010: ac1c e001 943e 1770 a6b0 b582 3ecf 4cd5 .....>.p....>.L. 0x0020: 5010 0103 2217 0000 P..."...
what codes sends and receives these packets? The first two twenty-byted segments are IP header (20 bytes without option) and TCP header (20 bytes without option) separately in these packets.
The source code snippet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Bool XQueryExtension ( register Display *dpy, _Xconst char *name, int *major_opcode, int *first_event, int *first_error) { xQueryExtensionReply rep; register xQueryExtensionReq *req; LockDisplay(dpy); GetReq(QueryExtension, req); req->nbytes = name ? strlen (name) : 0 ; req->length += (req->nbytes+(unsigned )3 )>>2 ; _XSend(dpy, name, (long )req->nbytes); (void ) _XReply (dpy, (xReply *)&rep, 0 , xTrue); *major_opcode = rep.major_opcode; *first_event = rep.first_event; *first_error = rep.first_error; UnlockDisplay(dpy); SyncHandle(); return (rep.present); }
The gdb log:
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 27 28 29 30 31 32 33 34 35 Starting program: /mnt/c/Users/lulu/Documents/github/demos/src/xdemos/glxgears [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Breakpoint 1, XextAddDisplay (extinfo=0x7ffff7e77380 <_dri2Info_data>, dpy=0x55555555d2a0, ext_name=0x7ffff7e76780 <dri2ExtensionName> "DRI2", hooks=0x7ffff7e767a0 <dri2ExtensionHooks>, nevents=0, data=0x0) at extutil.c:103 XInitExtension (dpy=dpy@entry=0x55555555d2a0, name=name@entry=0x7ffff7e76780 <dri2ExtensionName> "DRI2") at InitExt.c:44 XQueryExtension (dpy=dpy@entry=0x55555555d2a0, name=name@entry=0x7ffff7e76780 <dri2ExtensionName> "DRI2", major_opcode=major_opcode@entry=0x7fffffffd984, first_event=first_event@entry=0x7fffffffd988, first_error=first_error@entry=0x7fffffffd98c) at QuExt.c:39 $2 = { reqType = 0x62, pad = 0x0, length = 0x3, nbytes = 0x4, pad1 = 0x0, pad2 = 0x0 } $3 = { type = 0x1, pad1 = 0x0, sequenceNumber = 0xa, length = 0x0, present = 0x0, major_opcode = 0x0, first_event = 0x0, first_error = 0x0, pad3 = 0x0, pad4 = 0x0, pad5 = 0x0, pad6 = 0x0, pad7 = 0x0 }
$2
is Request packet content to VcXsrv, $3
is Reply packet content from VcXsrv. Even that we can notice the three-way handshake of TCP from the zero-lengthed packet in x110224.pcap.