-
Notifications
You must be signed in to change notification settings - Fork 185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dns: Parse packet in user space #2544
Conversation
61d056b
to
48150fe
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes handling the packets much easier - excited to see how we solve that for the image based gadgets 😄
90702e9
to
452dea3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only reviewed the first commit for now. I already have some comments and many questions 😅. Sorry if I commented things that are changed in the second commit, feel free to immediately resolve them.
@mauriciovasquezbernal Thanks for the change. I tested this change in the following way:
./kubectl-gadget trace dns -A ✔
K8S.NODE K8S.NAMESPACE K8S.POD PID TID COMM QR TYPE QTYPE NAME RCODE NUMANS…
minikube-docker 97501 57694 dockerd Q OUTGOING A dc.services.visualstudio.co… 0
ERRO[0004] decoding dns layer: resource record length exceeds data
minikube-docker 0 0 R OUTGOING A dc.services.visualstudio.co… NoError 23
minikube-docker 71848 71849 isc-worker0000 R HOST A dc.services.visualstudio.co… NoError 23
minikube-docker 97501 57693 dockerd Q OUTGOING AAAA dc.services.visualstudio.co… 0
minikube-docker 97501 57693 dockerd R HOST AAAA dc.services.visualstudio.co… NoError 13
minikube-docker 0 0 R OUTGOING AAAA dc.services.visualstudio.co… NoError 13
minikube-docker 71910 71911 isc-worker0000 R HOST AAAA dc.services.visualstudio.co… NoError 13 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting approach! Like Mike, looking forward to seeing this one implemented as image-based gadget.
The code looks good to me already from code inspection. I'll wait for the port params implementation and then I will test it.
452dea3
to
eec00f0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested and working as expected. LGTM!
3592eec
to
616a3d1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi!
I really like the idea, as it simplifies our code base.
But I have one concern with regard to the types.
Best regards.
// Map of DNS query to timestamp so we can calculate latency from query sent to answer received. | ||
struct query_key_t { | ||
__u64 pid_tgid; | ||
__u16 id; | ||
__u16 pad[3]; // this is needed, otherwise the verifier claims an invalid read from stack |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where exactly the verifier rejects the program?
When you this as a key? Or when you initialize it?
// This is hardcoded for now as the datapath assumes the DNS packet is UDP over IPv4 | ||
// without any options. Next iterations will fix this. | ||
// Ethernet + IP + UDP | ||
const dnsOff = 14 + 20 + 8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, add some documentation and links on the why of these magical values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is pretty clear that those are the size of the headers. I could add add links to the RFCs of those protocols but it's an overkill on my opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could add add links to the RFCs of those protocols but it's an overkill on my opinion.
Documenting is never overkill, please add them.
if !ok { | ||
event.QType = "UNASSIGNED" | ||
if len(dnsLayer.Questions) > 0 { | ||
question := dnsLayer.Questions[0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not understand something.
Before, we had this big array qTypeNames
, now we rely on this golang
package.
Sadly, the golang
package does not define as many types as our previous array:
https://pkg.go.dev/github.com/google/gopacket@v1.1.19/layers#DNSType
So, are we loosing some types by using this package? Or before we defined more types than needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question, I have no idea. I wanted to use gopacket as much as possible to parse this values as I think they are a good source of trust for that. @alban do you have any opinion here? Should we continue using our big array or switch to gopacket?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, it doesn't make sense to use gopacket parsing for some things and not for others. I agree gopacket is indeed a good source of truth, if we consider there is something missing, we should open a PR on gopacket instead of use a custom parsing. In this case in specific, honestly, I think people will mainly use the DNS gadget for tracing IPv4 and IPv6 request, and those are already included in the gopacket parsing. Said that, I suggest using the gopacket parsing also here.
616a3d1
to
c27a48c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi!
It works on my side:
$ sudo ./ig trace dns mauricio/parse-dns-userspace % u=
RUNTIME.CONTAINERNAME PID TID COMM QR TYPE QTYPE NAME RCODE NUMANSW…
test-trace-dns 21188 21189 isc-net-0000 Q OUTGOING A inspektor-gadget.io. 0
test-trace-dns 21188 21189 isc-net-0000 R HOST A inspektor-gadget.io. No Error 2
$ uname -a mauricio/parse-dns-userspace % u=
Linux pwmachine 6.5.0-21-generic #21~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Feb 9 13:32:52 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
But I still have some concerns regarding the DNS type.
Best regards.
Rcode: "NXDomain", | ||
Rcode: "Non-Existent Domain", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the width of the column be adapted?
pkg/gadgets/trace/dns/types/dns.go:
Rcode string `json:"rcode,omitempty" column:"rcode,minWidth:8"`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed it to 12.
The current logic tries to parse the full DNS packet in eBPF. This is diffcult to do a imposes some limitations, like not supporting: - DNS over TCP - Uncompressed messages - More than 8 answers This commit changes approach to parce the DNS packet on user space. Signed-off-by: Mauricio Vásquez <mauriciov@microsoft.com>
c27a48c
to
d772f2e
Compare
Opened #2574 as a follow up work on this., |
TODO:
Fixes #2008