Since last post were added loading of RAM-drive, using httpfs precaching and some other small updates and bugfixes, most of time was spent for testing.
Now rootpath option is used to specify location of root on web server. Also, I’ve found that bootp() doesn’t sets nameip (it was not usually needed for NFS loader, it’s enough to specify IP of server and resolving is not required. But in case of web0servers, which may use virtual servers for different domains for same IP – it’s needed to know domain name, and nameserver option is needed) and thus gives problems for code to work, so by default own DHCP client is used. If not domain name but IP is specified in rootpath, then bootp() may be used.
Loading of RAM-drive is optional, but was needed to test correct working of code. It’s done simply by adding few lines to loader.rc script. Actually, it’s possible use for example NFS after loading as root file system (by setting appropriate environment variables), but as long as pxe_http library code must be a little bit independent – best choice was to use RAM-drive (or additionaly to write kernel module for support httpfs. Last variant needed more time and knowledge, so it temporarily was thrown away).
RAM drive image was got from boot floppy image (mfsroot.gz). It contains needed for system installation files. So, after loading by pxe_http kernel+RAM drive it’s possible to install FreeBSD by choosing ftp as media source.
While testing code in LAN I’ve found that loader trys to get file by small portions (maximum 4096 bytes per request). It is not very optimal, so about month ago I was thinking about simple caching mechanism and now it works. For this purpose, httpfs need access to socket receive buffer (this is done to reduce memory usage, so cached information is actually stored in socket buffer, main problem is in removing from buffer header and watching when cached data is empty). Such ability breaks abstraction of code layers, but raises up connection speed and reduces load of http server. While testing it lowered downloading time from about one minute to 25-30 seconds. After setting lower waiting time in pxe_await.h, code response to incoming packets become higher, and downloading is performed in 15-25 seconds at LAN.
After caching was checked, I’ve started testing of code with remote server, that is really remote and situated in 12 hops from my home computer. Here was first surprise, TCP code was working really strange: some packets were never received. During debugging also bug with resending was fixed (segments were waiting to be acked bigger aequential number, then needed).
So, packets were not receiving and code not worked in WAN. I’ve spent many hours trying to make it work. Ed (my mentor) said simple idea – to tcpdump on server side. Well, I don’t know why this idea have not appeared in my mind itself. tcpdump showed, that all is ok – packets from me correctly are coming to server, and from server to me are also sent, however not acked. Debugging of pxe_core showed that they are not reaching my NIC. I’ve started comparing two dumps and found rather interesting thing: only packets with segment size fuly filled to 1460 (default TCP MSS in pxe_http) were not transmitted correctly. I’ve changed MSS to 1260 (10 hops * 20 bytes is about 200 bytes…) and code started working correctly. Packets were sent with Don’t fragment IP flag, so I think somewhere on the path to me router dropped them cause couldn’t sent it not fragmented. May be it’s just my ISP side problem.
After getting code working correctly in Internet, I’ve tested it on two different web servers (first uses Apache, second one – nginx), both worked correctly. And to make sure code is really working, I’ve managed my friend to try it from his home through ADSL modem (at my home, Internet is got through VPN via ISP Ethernet based network, so router at my home is second computer with pppoe client). It also worked.
Last check was to test again NFS loader after some changes in pxe_open() function. It also worked, so finally code seems ready to be tested widely and tarball of current version of code will be sent as result of GSoC.
Finally, I’ve wrote simple documentation, that may be useful for setting pxe_http to work or use it API. Well, it’s not covers every function of pxe_http code, but gives main information, needed to work with it.
Next two weeks I’m planning get more information about ipv6, spend summer time and do nothing usefull at all, except fixing any simple bugs found in code. Later I’ll try to add ipv6 support for pxe_http and may be implement some other ideas.