github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/gadgets/trace/sni/tracer/tracer.go (about) 1 // Copyright 2019-2024 The Inspektor Gadget authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //go:build !withoutebpf 16 17 package tracer 18 19 import ( 20 "context" 21 "errors" 22 "fmt" 23 "unsafe" 24 25 gadgetcontext "github.com/inspektor-gadget/inspektor-gadget/pkg/gadget-context" 26 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets" 27 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/sni/types" 28 "github.com/inspektor-gadget/inspektor-gadget/pkg/networktracer" 29 eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types" 30 ) 31 32 //go:generate go run github.com/cilium/ebpf/cmd/bpf2go -target bpfel -cc clang -cflags ${CFLAGS} -type event_t snisnoop ./bpf/snisnoop.c -- $CLANG_OS_FLAGS -I./bpf/ 33 34 const ( 35 TLSMaxServerNameLen = len(snisnoopEventT{}.Name) 36 ) 37 38 type Tracer struct { 39 *networktracer.Tracer[types.Event] 40 41 ctx context.Context 42 cancel context.CancelFunc 43 } 44 45 func NewTracer() (*Tracer, error) { 46 t := &Tracer{} 47 48 if err := t.install(); err != nil { 49 t.Close() 50 return nil, fmt.Errorf("installing tracer: %w", err) 51 } 52 53 return t, nil 54 } 55 56 // RunWorkaround is used by pkg/gadget-collection/gadgets/trace/sni/gadget.go to run the gadget 57 // after calling NewTracer() 58 func (t *Tracer) RunWorkaround() error { 59 if err := t.run(); err != nil { 60 t.Close() 61 62 return fmt.Errorf("running tracer: %w", err) 63 } 64 65 return nil 66 } 67 68 func parseSNIEvent(sample []byte, netns uint64) (*types.Event, error) { 69 bpfEvent := (*snisnoopEventT)(unsafe.Pointer(&sample[0])) 70 if len(sample) < int(unsafe.Sizeof(*bpfEvent)) { 71 return nil, errors.New("invalid sample size") 72 } 73 74 timestamp := gadgets.WallTimeFromBootTime(bpfEvent.Timestamp) 75 76 name := gadgets.FromCString(bpfEvent.Name[:]) 77 if len(name) == 0 { 78 return nil, nil 79 } 80 81 event := types.Event{ 82 Event: eventtypes.Event{ 83 Type: eventtypes.NORMAL, 84 Timestamp: timestamp, 85 }, 86 Pid: bpfEvent.Pid, 87 Tid: bpfEvent.Tid, 88 Uid: bpfEvent.Uid, 89 Gid: bpfEvent.Gid, 90 WithMountNsID: eventtypes.WithMountNsID{MountNsID: bpfEvent.MountNsId}, 91 WithNetNsID: eventtypes.WithNetNsID{NetNsID: netns}, 92 Comm: gadgets.FromCString(bpfEvent.Task[:]), 93 94 Name: name, 95 } 96 97 return &event, nil 98 } 99 100 // --- Registry changes 101 102 func (g *GadgetDesc) NewInstance() (gadgets.Gadget, error) { 103 return &Tracer{}, nil 104 } 105 106 func (t *Tracer) Init(gadgetCtx gadgets.GadgetContext) error { 107 if err := t.install(); err != nil { 108 t.Close() 109 return fmt.Errorf("installing tracer: %w", err) 110 } 111 112 t.ctx, t.cancel = gadgetcontext.WithTimeoutOrCancel(gadgetCtx.Context(), gadgetCtx.Timeout()) 113 return nil 114 } 115 116 func (t *Tracer) install() error { 117 networkTracer, err := networktracer.NewTracer[types.Event]() 118 if err != nil { 119 return fmt.Errorf("creating network tracer: %w", err) 120 } 121 t.Tracer = networkTracer 122 return nil 123 } 124 125 func (t *Tracer) run() error { 126 spec, err := loadSnisnoop() 127 if err != nil { 128 return fmt.Errorf("loading asset: %w", err) 129 } 130 131 err = t.Tracer.Run(spec, types.Base, parseSNIEvent) 132 if err != nil { 133 return fmt.Errorf("setting network tracer spec: %w", err) 134 } 135 136 return nil 137 } 138 139 func (t *Tracer) Run(gadgetCtx gadgets.GadgetContext) error { 140 if err := t.run(); err != nil { 141 return nil 142 } 143 144 <-t.ctx.Done() 145 return nil 146 } 147 148 func (t *Tracer) Close() { 149 if t.cancel != nil { 150 t.cancel() 151 } 152 153 if t.Tracer != nil { 154 t.Tracer.Close() 155 } 156 }