aboutsummaryrefslogtreecommitdiff
path: root/lib/dns/server.go
AgeCommit message (Collapse)Author
2026-03-26lib/dns: refactoring DoT and DoH to use address instead of portShulhan
Using port makes the IP address of DoT and DoH listen on the same address with UDP. If we set ListenAddress to 0.0.0.0 and TLS termination is handled by proxy, this cause DoT and DoH will also listen on all addresses.
2026-02-02lib/dns: remove unnessary log prefix on forwarderShulhan
The "tag" prefix already indicate the forwarder type.
2026-02-02lib/dns: minimize use of appendShulhan
In handleDoHRequest, we did not need to call append, just copy it as is. In DoTClient and TCPClient, since we already do make, use direct copy instead of another append.
2026-02-02lib/dns: use separate ServeMux for handling DoHShulhan
Using the [http.DefaultServeMux] will cause panic when the server restarted automatically.
2026-02-02lib/dns: skip caching empty answer only for query type AShulhan
Previously, we did not store response with empty RR answer for all record types. Meanwhile, some domains still does not have AAAA(28) and HTTPS(65) records set, but browser will requesting them. So, to minimize traffic for those query we skip caching only for query type A and cache the rest of types.
2026-02-02lib/dns: remove DebugLevelDNSShulhan
The DebugLevelDNS log the error on DNS level, for example empty answer, error on name, class not implemented, refused; which is now on by default.
2026-02-02lib/dns: changes the request's kind field to stringShulhan
This is to minimize lookup on map each time we need the string representation.
2026-02-02lib/dns: add option to set hook on server when receiving answerShulhan
The hook function, OnAnswerReceived, will be triggered when server receive valid answer but before its put to caches.
2026-01-26lib/dns: print the answer TTL in DebugLevelCacheShulhan
The log level cache changed to the following format, ... {MSG_ID QNAME TYPE TTL} ... where MSG_ID is the message ID, QNAME is the question name, TYPE is the type of question, and TTL is the time-to-live of the answer. This changes require adding field TTL to Answer and exporting the field Message.
2026-01-26lib/dns: simplify log message for DebugLevelCacheShulhan
For each logged request, there should be one line of response logged, success or fail. This changes remove redundant log "^" (request forwarded) and "~" (answer is expired). The final log would be only "+" (new answer cached), or "#" (answer updated), or "!" (error).
2025-02-04all: remove the nolint tagsShulhan
The "nolint" tag is used to ignore lines from being processed by golangci-lint. Since we are not using golangci-lint anymore, now and in the future, those lines can be removed.
2025-01-23all: use for-range with numericShulhan
Go 1.22 now support for-range on numeric value.
2025-01-22lib/bytes: replace Copy and Concat with standard libraryShulhan
Since Go 1.20, the standard bytes package have the Copy function. Since Go 1.22, the standard slices package have the Concat function.
2025-01-17lib/dns: improve the logging prefix on serveTCPClientShulhan
The serveTCPClient is used to serve TCP and DoT clients. Previously, the error returned from this method is prefixed based on the kind, for example serveTCPClient TCP: ... serveTCPClient DoT: ... This changes pass the log prefix to the method so now it become serveTCPClient: ... serveDoTClient: ...
2024-04-13lib/dns: make server accept record type ANYShulhan
The record type ANY contains multiple A, AAAA or any known resource records that we already support.
2024-04-12lib/dns: return errInvalidMessage when received message cannot be parsedShulhan
By returning error errInvalidMessage, the caller can check whether the issue is in connection or in the message itself. If the issue is not in the message, the caller needs to re-create the connection.
2024-03-27lib/dns: refactor [Message.Unpack] to [UnpackMessage]Shulhan
The previous API for Message is a little bit weird. Its provides creating Message manually, but expose the method [UnpackHeaderQuestion], meanwhile the field packet itself is unexported. In order to make it more clear we refactor [Message.Unpack] to function [UnpackMessage] that accept raw DNS packet.
2024-03-26lib/dns: implements RFC 9460 for SVCB RR and HTTPS RRShulhan
2024-03-05all: comply with linter recommendations #3Shulhan
For HTTP server that use TLS, set the minimum TLS version and ReadHeaderTimeout to mitigate slowloris attack. For HTTP client or server that parameterize the use of InsecureSkipVerify, annotate the line with "nolint:gosec" to allow the code pass the check. Library that still use sha1, in example in DKIM and TOTP, skip the warnings by annotating the line with "nolint:gosec". A pointer variable now allocated their address before assigning its value. Any error that returned now wrapped using "%w". Also, replace error checking using [errors.Is] or [errors.As] instead of using equal or not-equal operators. In "lib/http", replace any usage of "math/rand" with "crypto/rand". Any call of [math/big.Rat.SetString] now annotated with "nolint:gosec" since its false positive, the issue has been fixed in Go >= 1.17.7. Any switch case that does not cover the rest of the possible values now handled by adding the cases or by replacing the "default" case with the rest of values.
2024-03-05all: comply with linter recommendations #2Shulhan
HTTP request now implicitly create request with context. Any false positive related to not closing HTTP response body has been annotated with "nolint:bodyclose". In the example code, use consistent "// Output:" comment format, by prefixing with single space. Any comment on code now also prefixing with single space. An error returned without variables now use [errors.New] instead of [fmt.Errorf]. Any error returned using [fmt.Errorf] now wrapped using "%w" instead of "%s". Also, replace error checking using [errors.Is] or [errors.As], instead of using equal/not-equal operator. Any statement like "x = x OP y" now replaced with "x OP= y". Also, swap statement is simplified using "x, y = y, x". Any switch statement with single case now replaced with if-condition. Any call to defer on function or program that call [os.Exit], now replaced by calling the deferred function directly. Any if-else condition now replaced with switch statement, if possible.
2024-03-02all: move the repository to "git.sr.ht/~shulhan/pakakeh.go"Shulhan
There are several reasons that why we move from github.com. First, related to the name of package. We accidentally name the package with "share" a common word in English that does not reflect the content of repository. By moving to other repository, we can rename it to better and unique name, in this "pakakeh.go". Pakakeh is Minang word for tools, and ".go" suffix indicate that the repository related to Go programming language. Second, supporting open source. The new repository is hosted under sourcehut.org, the founder is known to support open source, and all their services are licensed under AGPL, unlike GitHub that are closed sources. Third, regarding GitHub CoPilot. The GitHub Terms of Service [1], allow any public content that are hosted there granted them to parse the content. On one side, GitHub helps and flourish the open source, but on another side have an issues regarding scraping the copyleft license [2]. [1]: https://docs.github.com/en/site-policy/github-terms/github-terms-of-service#4-license-grant-to-us [2]: https://githubcopilotinvestigation.com
2024-02-25lib/dns: ignore invalid messageShulhan
If Query return a message but the failed to unpack due to invalid format, for example unpackOPT: data length is out of range ignore it instead of disconnect the client connection.
2024-02-04lib/dns: change the log mechanism by mode instead of by levelShulhan
This changes introduce three mode of debug: - DebugLevelDNS: log error on DNS level, in example empty answer, ERR_NAME (domain name is invalid or not known) and so on. - DebugLevelCache: log cache operations. - DebugLevelConnPacket: log low level connection and package, including request and response.
2023-12-13all: fix linter warnings reported by reviveShulhan
There are some reports that I disagree with revive, in example, code should not declare the type after variables. In my opinion, on some cases, declaring the type make the code more readable and explicit. Since I did not want to add new configuration file, we changes it and follow revive for now.
2023-08-06lib/dns: fix leaking internal zoneShulhan
Previously, if the server have internal zone "my.internal" and the client query "sub.my.internal" that does not exist in the zone, the server then forward the query to parent name server. This cause the internal zone and its domains leaked to parent name server. This changes fix this issue by checking if the query is subset of internal zone Origin if domain does not exist, and response with error code 3 (ERR_NAME) with the Zone SOA in Authority.
2023-05-24lib/dns: do not cache empty answersShulhan
The use case if one use and switch between two different networks with internal zone, frequently. For example, if on network Y they have domain MY.Y and current connection is X, request to MY.Y will return an empty answers. Once they connect to Y again, any request to MY.Y will not be possible because rescached caches contains empty answer for MY.Y.
2023-05-20lib/dns: add option to set debug level in ServerOptionsShulhan
This options replace the global debug package.
2023-03-25lib/dns: fix all lint warnings suggested by revive and fieldalignmentShulhan
2022-06-24lib/dns: use Shutdown to stop DoH serverShulhan
Using Shutdown allow active connection not interrupted but it may cause delay when restarting the server. While at it, set the doh and dot server instance to nil to release the resource, in case the Server need to start again.
2022-05-30lib/dns: move all caches operations from Server to Caches typeShulhan
Previously all caches operation are tied to the Server type. In order to separate the responsibilities between server and caches, we move all caches operations to Cache type.
2022-05-30lib/dns: export the Caches type and field on ServerShulhan
The idea is move all server's caches operations (methods) to this type later.
2022-05-30lib/dns: split storage between internal and external cachesShulhan
Previously, the indexed caches for internal (records from hosts or zone files) and external (records from parent name servers) are stored inside single map. This changes split those internal and external caches into two maps, so any operation on one caches does not affect the other one, and vice versa.
2022-05-17lib/dns: return the removed record on caches RemoveCachesByRRShulhan
If the record being removed found on caches, it will return it; otherwise it will return nil without error.
2022-05-12all: rewrite all codes to use "var" instead of ":="Shulhan
Using ":=" simplify the code but we lose the type. For example, v := F() The only way we know what the type of v is by inspecting the function F. Another disadvantages of using ":=" may cause extra variables allocation where two or more variables with same type is declared inside body of function where it could be only one. While at it, we split the struct for test case into separate type.
2022-05-09all: reformat all codes using gofmt 1.19 (the Go tip)Shulhan
2022-04-15lib/dns: add method CachesClear to remove all cachesShulhan
2022-04-15lib/dns: refactor Server RemoveCachesByNames to return removed AnswerShulhan
Previously, RemoveCachesByNames does not return anything, its only print the domain name being removed if debugging level is set to >= 1. This changes rewrite the RemoveCachesByNames to return list of Answer being removed to allower the caller to inspect and/or print the Answer.
2022-04-06all: replace any usage of ioutil package with os or ioShulhan
Since Go 1.16, the ioutil package has been deprecated. This changes replace any usage that use functions from ioutil package with their replacement from package os or package io.
2021-11-16lib/dns: remove ineffectual assignment to err in Server runTCPForwarderShulhan
2021-11-15lib/dns: realign all struct fieldsShulhan
Using the fieldalignment, we got the following output, answer.go:15:13: struct with 56 pointer bytes could be 24 = 32 bytes caches.go:27:13: struct with 24 pointer bytes could be 16 = 8 dot_client.go:20:16: struct with 16 pointer bytes could be 8 = 8 hosts_file.go:24:16: struct with 64 pointer bytes could be 48 = 16 message.go:53:14: struct of size 176 could be 168 = 8 rdata_mx.go:20:14: struct with 16 pointer bytes could be 8 = 8 rdata_opt.go:18:15: struct with 16 pointer bytes could be 8 = 8 rdata_srv.go:16:15: struct with 64 pointer bytes could be 56 = 8 rdata_wks.go:30:15: struct with 40 pointer bytes could be 32 = 8 request.go:20:14: struct with 32 pointer bytes could be 24 = 8 resource_record.go:24:21: struct with 56 pointer bytes could be 40 = 16 server.go:76:13: struct with 120 pointer bytes could be 112 = 8 server_options.go:20:20: struct of size 240 could be 224 = 16 tcp_client.go:21:16: struct with 40 pointer bytes could be 24 = 16 udp_client.go:24:16: struct with 24 pointer bytes could be 16 = 8 udp_client_pool.go:25:20: struct with 24 pointer bytes could be 16 = 8 zone_file.go:22:15: struct with 128 pointer bytes could be 120 = 8 zone_parser.go:53:17: struct with 88 pointer bytes could be 72 = 16 Turns out the struct that we frequently used, answer and resource_record, is not optimized. This changes reorder all structs field to save space in memory.
2021-11-14lib/dns: refactoring, introduce new type RecordClassShulhan
Previously, the record class is represented by uint16 using prefix QueryClassXxx. This changes make the record class to be an independent type, to make code more strict (prevent passing invalid value), and readable.
2021-11-14lib/dns: refactoring, create type RecordType to represent type of RRShulhan
Previously, we use uint16 to represent type for ResourceRecord Type or Question type. To make the code more strict, where parameter or return value, must be expected as record type, we add new type to represent the RR type: RecordType. This changes also rename any variable name of QType or qtype to RType or rtype because QType is misleading. The type defined the ResourceRecord to be queried not only question.
2021-11-13lib/dns: remove unnecessary string convertionShulhan
2021-11-13lib/dns: make the TCP forwarders as complementary of UDPShulhan
The TCP forwarders only active when client send the DNS request as TCP. When the server receive that request it should also forward the request as TCP not as UDP to prevent the truncated response. Another use case for TCP is when the response is truncated, the client will send the query back through TCP connection. The server should forward this request using TCP instead of UDP.
2021-11-13lib/dns: remove the fallback name servers (NS) from server optionsShulhan
The original idea of fallback NS is to send the query to the one define to original resolv.conf, instead of using the one defined by user in ServerOptions NameServers, when an error occured. But, most of error usually caused by network (disconnected, time out), so re-sending query to fallback NS does not have any effect if the network it self is not working. This changes remove the unnecessary and complex fallback NS from server.
2021-11-12lib/dns: log the question when forward failedShulhan
2021-11-11lib/dns: simplify parse name servers on server optionsShulhan
Instead of returning four variables, the parseNameServers now have parameter isPrimary to set the primary address or fallback address.
2021-11-11lib/dns: do not cache truncated answerShulhan
Previously only answer with non-zero response code is ignored. This changes ignore also answer where response header is truncated.
2021-11-11lib/dns: use different packet between UDP and TCP messagesShulhan
Previously, all packet size for reading and sending the message is fixed to 4096, even on UDP. This changes set the UDP packet size maximum to 512 bytes and others to 4096 bytes. While at it, minimize copying packet if its not reusable inside a method.
2021-11-08lib/dns: add support to save and load caches to/from storageShulhan
The CachesSave method write the non-local answers into an io.Writer, encoded with gob. The CachesLoad method load the gob encoded answers from an io.Reader.