Skip to content

Commit f2d32d4

Browse files
committed
1 parent 48d91be commit f2d32d4

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

netfilter.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ import (
3535
"fmt"
3636
"github.com/google/gopacket"
3737
"github.com/google/gopacket/layers"
38+
"os"
39+
"sync"
40+
"time"
3841
"unsafe"
3942
)
4043

@@ -61,6 +64,7 @@ type NFQueue struct {
6164
qh *C.struct_nfq_q_handle
6265
fd C.int
6366
packets chan NFPacket
67+
idx uint32
6468
}
6569

6670
//Verdict for a packet
@@ -79,6 +83,9 @@ const (
7983
NF_DEFAULT_PACKET_SIZE uint32 = 0xffff
8084
)
8185

86+
var theTable = make(map[uint32]*chan NFPacket, 0)
87+
var theTabeLock sync.RWMutex
88+
8289
//Create and bind to queue specified by queueId
8390
func NewNFQueue(queueId uint16, maxPacketsInQueue uint32, packetSize uint32) (*NFQueue, error) {
8491
var nfq = NFQueue{}
@@ -98,7 +105,11 @@ func NewNFQueue(queueId uint16, maxPacketsInQueue uint32, packetSize uint32) (*N
98105
}
99106

100107
nfq.packets = make(chan NFPacket)
101-
if nfq.qh, err = C.CreateQueue(nfq.h, C.u_int16_t(queueId), unsafe.Pointer(&nfq.packets)); err != nil || nfq.qh == nil {
108+
nfq.idx = uint32(time.Now().UnixNano())
109+
theTabeLock.Lock()
110+
theTable[nfq.idx] = &nfq.packets
111+
theTabeLock.Unlock()
112+
if nfq.qh, err = C.CreateQueue(nfq.h, C.u_int16_t(queueId), C.u_int32_t(nfq.idx)); err != nil || nfq.qh == nil {
102113
C.nfq_close(nfq.h)
103114
return nil, fmt.Errorf("Error binding to queue: %v\n", err)
104115
}
@@ -130,6 +141,9 @@ func NewNFQueue(queueId uint16, maxPacketsInQueue uint32, packetSize uint32) (*N
130141
func (nfq *NFQueue) Close() {
131142
C.nfq_destroy_queue(nfq.qh)
132143
C.nfq_close(nfq.h)
144+
theTabeLock.Lock()
145+
delete(theTable, nfq.idx)
146+
theTabeLock.Unlock()
133147
}
134148

135149
//Get the channel for packets
@@ -142,15 +156,23 @@ func (nfq *NFQueue) run() {
142156
}
143157

144158
//export go_callback
145-
func go_callback(queueId C.int, data *C.uchar, len C.int, cb *chan NFPacket) Verdict {
159+
func go_callback(queueId C.int, data *C.uchar, len C.int, idx uint32) Verdict {
146160
xdata := C.GoBytes(unsafe.Pointer(data), len)
147161
packet := gopacket.NewPacket(xdata, layers.LayerTypeIPv4, gopacket.DecodeOptions{Lazy: true, NoCopy: true})
148162
p := NFPacket{verdictChannel: make(chan Verdict), Packet: packet}
163+
theTabeLock.RLock()
164+
cb, ok := theTable[idx]
165+
theTabeLock.RUnlock()
166+
if !ok {
167+
fmt.Fprintf(os.Stderr, "Dropping, unexpectedly due to bad idx=%d\n", idx)
168+
return NF_DROP
169+
}
149170
select {
150171
case (*cb) <- p:
151172
v := <-p.verdictChannel
152173
return v
153174
default:
175+
fmt.Fprintf(os.Stderr, "Dropping, unexpectedly due to no recv, idx=%d\n", idx)
154176
return NF_DROP
155177
}
156178
}

netfilter.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,29 @@
2727
#include <linux/netfilter.h>
2828
#include <libnetfilter_queue/libnetfilter_queue.h>
2929

30-
extern uint go_callback(int id, unsigned char* data, int len, void** cb_func);
30+
extern uint go_callback(int id, unsigned char* data, int len, u_int32_t idx);
3131

3232
static int nf_callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *cb_func){
3333
uint32_t id = -1;
3434
struct nfqnl_msg_packet_hdr *ph = NULL;
3535
unsigned char *buffer = NULL;
3636
int ret = 0;
3737
int verdict = 0;
38+
u_int32_t idx;
3839

3940
ph = nfq_get_msg_packet_hdr(nfa);
4041
id = ntohl(ph->packet_id);
4142

4243
ret = nfq_get_payload(nfa, &buffer);
43-
verdict = go_callback(id, buffer, ret, cb_func);
44+
idx = (uint32_t)((uintptr_t)cb_func);
45+
verdict = go_callback(id, buffer, ret, idx);
4446

4547
return nfq_set_verdict(qh, id, verdict, 0, NULL);
4648
}
4749

48-
static inline struct nfq_q_handle* CreateQueue(struct nfq_handle *h, u_int16_t queue, void* cb_func)
50+
static inline struct nfq_q_handle* CreateQueue(struct nfq_handle *h, u_int16_t queue, u_int32_t idx)
4951
{
50-
return nfq_create_queue(h, queue, &nf_callback, cb_func);
52+
return nfq_create_queue(h, queue, &nf_callback, (void*)((uintptr_t)idx));
5153
}
5254

5355
static inline void Run(struct nfq_handle *h, int fd)

0 commit comments

Comments
 (0)