Well, first version of DNS client was working about a week ago, but it had one problem: some of domain names were resolved, others were not. In fact, even packets were not returned in reply to sended requests. I’ve checked request making function and found no problems, added verbosity of debug information and found no problems still. After some thoughts, I’ve decided that only lower levels of code may produce such fault. And after some hunting for bugs, one fat error was found at UDP checksum calculation. UDP checksum is calculated for pseudo IP header, UDP header and data. I was calculating this sum separately (for pseudo header and for rest) and after that adding them together. On this stage there was error and routers, which check UDP checksums, just were dropping this packets. When local DNS server was able to resolve cached name (requested by other DNS clients in LAN) it was answering, cause it was not checking sums.
DNS clients (and currently developing DHCP client) are implemented using UDP sockets. For sockets I’ve added cyclic buffers and routines to work with them. UDP callback functions stores datagrams (which passed filters) to socket recv_buffer, heading structure with source address information that is used by pxe_recvfrom(). There is no ability to know if datagram is truncated now. if user recv’ed less then total size of datagram – rest of it is dropped.
Added after this pxe_bind() function required using of socket state. Now it’s not only free/used, but binded/connected/established. Binded socket has only one part of filter set strictly, connected – both source and destination related parts, established is unused, but will be used later with TCP.
DNS client is used in pxe_gethostbyname() function which returns ip4 addr by domain name. Need testing of CNAME handling, if there is no A record in additional or answer section (in this case request resended with CNAME to resolve. In my tests there was no DNS server, which returned somedomain CNAME canonical_domain without leading canonical _domain A ip.ip.ip.ip.). Resolved names are not cached, I don’t think it’s needed for this project. Meanwhile testing, i’ve found funny thing: www.google.ru is CNAME to www.google.com, but google.ru is just A to set of ip’s (by the way DNS client takes first appropriate record as ip resolved for given name). So just three letters and you are logically in other network.
UDP sockets seems working (I’ll test it later on NFS client in pxe.c to be sure there are no bugs). pxe_sendto() moves socket to connected state if it was not binded before (it’s used in DNS client, may be it’s better to change behaviour of this function)
Next to implement:
- universal waiting mechanism for packets to avoid repeating of cycles in every module. It will be similar to Etherboot or to the uIP await functions.
- getting default gateway/nameserver from DHCP server. Although, it’s possible to change them manually (‘pxe ns’ and ‘pxe route’ commands in testing module) it must be get by default from DHCP server (also, in DHCP packet may be returned host from which perform downloading of files via http. this need adding user option to packet). For some reasons cached DHCPACK packet data in PXE is filled with zeroes (during downloading of NBP, TFTP has this information, it shows it, but returned by PXE API call data contains no information in options section. May be I need check legacy BOOTP section if it hides needed info instead of filename and servername)
- start implementing TCP recieve/send packets function.
- add raw_handlers. Currently, if protocol callback function does not think packet useful for itself, function drops it. raw_handler for protocol will be callback, which will get this packets. it’ll be set by users. It’ll no change currently working code except of return values of callback functions.