Skip to content

Commit

Permalink
RawSocket: handle packets that are larger than a single buffer
Browse files Browse the repository at this point in the history
VPWS: fix premature exit of push() method after packet discard
  • Loading branch information
alexandergall committed Feb 20, 2014
1 parent 51122bb commit 0e3116f
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 13 deletions.
12 changes: 9 additions & 3 deletions src/apps/socket/dev.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,17 @@ end

function dev:receive()
assert(self.fd)
local size = C.msg_size(self.fd)
assert(size ~= -1)
local p = packet.allocate()
local b = buffer.allocate()
local s = C.receive_packet(self.fd, b)
local nbuffers = math.ceil(size/buffer.size)
assert(nbuffers <= C.PACKET_IOVEC_MAX)
for i = 1, nbuffers do
local b = buffer.allocate()
packet.add_iovec(p, b, 0)
end
local s = C.receive_packet(self.fd, p)
assert(s ~= -1)
packet.add_iovec(p, b, s)
return p
end

Expand Down
42 changes: 35 additions & 7 deletions src/apps/socket/io.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdint.h>
#include <strings.h>
Expand Down Expand Up @@ -31,23 +32,50 @@ int send_packet(int fd, struct packet *p) {
return(0);
}

int receive_packet(int fd, struct buffer *b) {
int receive_packet(int fd, struct packet *p) {
struct msghdr msg;
struct iovec iovec;
ssize_t s;
struct iovec iovecs[p->niovecs];
int i;
ssize_t s, len;

bzero(&msg, sizeof(msg));
iovec.iov_base = b->pointer;
iovec.iov_len = b->size;
msg.msg_iov = &iovec;
msg.msg_iovlen = 1;
for (i=0; i<p->niovecs; i++) {
iovecs[i].iov_base = p->iovecs[i].buffer->pointer;
iovecs[i].iov_len = p->iovecs[i].buffer->size;
}
msg.msg_iov = iovecs;
msg.msg_iovlen = p->niovecs;
if ((s = recvmsg(fd, &msg, 0)) == -1) {
perror("recvmsg");
return(-1);
}
if (msg.msg_flags && MSG_TRUNC) {
printf("truncated\n");
return(-1);
}
len = s;
for (i=0; i<p->niovecs; i++) {
ssize_t iov_len = msg.msg_iov[i].iov_len;
if (len > iov_len) {
p->iovecs[i].length = iov_len;
len -= iov_len;
} else {
p->iovecs[i].length = len;
}
}
p->length = s;
return(s);
}

int msg_size(int fd) {
int size;
if (ioctl(fd, FIONREAD, &size) == -1) {
perror("get message size");
return(-1);
}
return(size);
}

int can_receive(int fd) {
fd_set fds;
struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
Expand Down
3 changes: 2 additions & 1 deletion src/apps/socket/io.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
int send_packet(int, struct packet *);
int receive_packet(int, struct buffer *);
int receive_packet(int, struct packet *);
int can_transmit(int);
int can_receive(int);
int msg_size(int);
4 changes: 2 additions & 2 deletions src/apps/vpn/vpws.lua
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ function vpws:push()
else
-- Packet doesn't belong to VPN, discard
packet.deref(p)
return
p = nil
end
end
app.transmit(l_out, p)
if p then app.transmit(l_out, p) end
end
end
end
Expand Down

0 comments on commit 0e3116f

Please sign in to comment.