summaryrefslogtreecommitdiff
path: root/netcon
diff options
context:
space:
mode:
Diffstat (limited to 'netcon')
-rw-r--r--netcon/NetconEthernetTap.cpp56
-rwxr-xr-xnetcon/intercept.c82
-rwxr-xr-xnetcon/libintercept.so.1.0bin53400 -> 53656 bytes
3 files changed, 97 insertions, 41 deletions
diff --git a/netcon/NetconEthernetTap.cpp b/netcon/NetconEthernetTap.cpp
index 5ef52b72..0921f460 100644
--- a/netcon/NetconEthernetTap.cpp
+++ b/netcon/NetconEthernetTap.cpp
@@ -503,7 +503,7 @@ int NetconEthernetTap::send_return_value(int fd, int retval, int _errno = 0)
[I] EBADF - The descriptor is invalid.
[I] ECONNABORTED - A connection has been aborted.
[i] EFAULT - The addr argument is not in a writable part of the user address space.
- [ ] EINTR - The system call was interrupted by a signal that was caught before a valid connection arrived; see signal(7).
+ [-] EINTR - The system call was interrupted by a signal that was caught before a valid connection arrived; see signal(7).
[ ] EINVAL - Socket is not listening for connections, or addrlen is invalid (e.g., is negative).
[I] EINVAL - (accept4()) invalid value in flags.
[I] EMFILE - The per-process limit of open file descriptors has been reached.
@@ -806,6 +806,12 @@ void NetconEthernetTap::handle_retval(PhySocket *sock, void **uptr, unsigned cha
* @param structure containing the data and parameters for this client's RPC
*
+ i := should be implemented in intercept lib
+ I := is implemented in intercept lib
+ X := is implemented in service
+ ? := required treatment Unknown
+ - := Not needed
+
[ ] EACCES - The address is protected, and the user is not the superuser.
[X] EADDRINUSE - The given address is already in use.
[I] EBADF - sockfd is not a valid descriptor.
@@ -876,10 +882,16 @@ void NetconEthernetTap::handle_bind(PhySocket *sock, void **uptr, struct bind_st
* @param structure containing the data and parameters for this client's RPC
*
- [?] EADDRINUSE - Another socket is already listening on the same port.
- [X] EBADF - The argument sockfd is not a valid descriptor.
- [i] ENOTSOCK - The argument sockfd is not a socket.
- [i] EOPNOTSUPP - The socket is not of a type that supports the listen() operation.
+ i := should be implemented in intercept lib
+ I := is implemented in intercept lib
+ X := is implemented in service
+ ? := required treatment Unknown
+ - := Not needed
+
+[?] EADDRINUSE - Another socket is already listening on the same port.
+[I] EBADF - The argument sockfd is not a valid descriptor.
+[I] ENOTSOCK - The argument sockfd is not a socket.
+[I] EOPNOTSUPP - The socket is not of a type that supports the listen() operation.
*/
void NetconEthernetTap::handle_listen(PhySocket *sock, void **uptr, struct listen_st *listen_rpc)
@@ -890,6 +902,10 @@ void NetconEthernetTap::handle_listen(PhySocket *sock, void **uptr, struct liste
fprintf(stderr, "handle_listen(): PCB is already in listening state.\n");
return;
}
+
+ // TODO: Implement liste_with_backlog
+ // FIXME: Correct return values from this method, most is handled in intercept lib
+
struct tcp_pcb* listening_pcb = lwipstack->tcp_listen(conn->pcb);
if(listening_pcb != NULL) {
conn->pcb = listening_pcb;
@@ -924,13 +940,17 @@ void NetconEthernetTap::handle_listen(PhySocket *sock, void **uptr, struct liste
* @param structure containing the data and parameters for this client's RPC
*
- TODO: set errno appropriately
+ i := should be implemented in intercept lib
+ I := is implemented in intercept lib
+ X := is implemented in service
+ ? := required treatment Unknown
+ - := Not needed
[-] EACCES - Permission to create a socket of the specified type and/or protocol is denied.
- [?] EAFNOSUPPORT - The implementation does not support the specified address family.
- [?] EINVAL - Unknown protocol, or protocol family not available.
- [?] EINVAL - Invalid flags in type.
- [i] EMFILE - Process file table overflow.
+ [I] EAFNOSUPPORT - The implementation does not support the specified address family.
+ [I] EINVAL - Unknown protocol, or protocol family not available.
+ [I] EINVAL - Invalid flags in type.
+ [I] EMFILE - Process file table overflow.
[i] ENFILE - The system limit on the total number of open files has been reached.
[X] ENOBUFS or ENOMEM - Insufficient memory is available. The socket cannot be created until sufficient resources are freed.
[?] EPROTONOSUPPORT - The protocol type or the specified protocol is not supported within this domain.
@@ -974,23 +994,29 @@ void NetconEthernetTap::handle_socket(PhySocket *sock, void **uptr, struct socke
* @param PhySocket associated with this RPC connection
* @param structure containing the data and parameters for this client's RPC
- --- Error handling in this method will only catch problems which are immeidately
+ --- Error handling in this method will only catch problems which are immedately
apprent. Some errors will need to be caught in the nc_connected(0 callback
- [i] EACCES - For UNIX domain sockets, which are identified by pathname: Write permission is denied ...
+ i := should be implemented in intercept lib
+ I := is implemented in intercept lib
+ X := is implemented in service
+ ? := required treatment Unknown
+ - := Not needed
+
+ [-] EACCES - For UNIX domain sockets, which are identified by pathname: Write permission is denied ...
[ ] EACCES, EPERM - The user tried to connect to a broadcast address without having the socket broadcast flag enabled ...
[i] EADDRINUSE - Local address is already in use.
[?] EAFNOSUPPORT - The passed address didn't have the correct address family in its sa_family field.
[ ] EAGAIN - No more free local ports or insufficient entries in the routing cache.
[ ] EALREADY - The socket is nonblocking and a previous connection attempt has not yet been completed.
- [ ] EBADF - The file descriptor is not a valid index in the descriptor table.
+ [I] EBADF - The file descriptor is not a valid index in the descriptor table.
[ ] ECONNREFUSED - No-one listening on the remote address.
[i] EFAULT - The socket structure address is outside the user's address space.
[ ] EINPROGRESS - The socket is nonblocking and the connection cannot be completed immediately.
- [?] EINTR - The system call was interrupted by a signal that was caught.
+ [-] EINTR - The system call was interrupted by a signal that was caught.
[X] EISCONN - The socket is already connected.
[?] ENETUNREACH - Network is unreachable.
- [ ] ENOTSOCK - The file descriptor is not associated with a socket.
+ [I] ENOTSOCK - The file descriptor is not associated with a socket.
[X] ETIMEDOUT - Timeout while attempting connection.
*
diff --git a/netcon/intercept.c b/netcon/intercept.c
index 5060aa2c..4762b309 100755
--- a/netcon/intercept.c
+++ b/netcon/intercept.c
@@ -528,6 +528,16 @@ int socket(SOCKET_SIG)
return -EAFNOSUPPORT;
if (socket_type < 0 || socket_type >= SOCK_MAX)
return -EINVAL;
+ /* Check that we haven't hit the soft-limit file descriptors allowed */
+ /* FIXME: Find number of open fds
+ struct rlimit rl;
+ getrlimit(RLIMIT_NOFILE, &rl);
+ if(sockfd >= rl.rlim_cur){
+ errno = EMFILE;
+ return -1;
+ }
+ */
+ /* FIXME: detect ENFILE condition */
#endif
#ifdef DUMMY
@@ -597,8 +607,21 @@ int socket(SOCKET_SIG)
connect() intercept function */
int connect(CONNECT_SIG)
{
- int err;
+#ifdef CHECKS
+ /* Check that this is a valid fd */
+ if(fcntl(__fd, F_GETFD) < 0) {
+ return -1;
+ errno = EBADF;
+ }
+ /* Check that it is a socket */
+ int sock_type;
+ socklen_t sock_type_len = sizeof(sock_type);
+ if(getsockopt(__fd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len) < 0) {
+ errno = ENOTSOCK;
+ return -1;
+ }
/* FIXME: Check that address is in user space, return EFAULT ? */
+#endif
#ifdef DUMMY
dwr("connect(%d)\n", __fd);
@@ -606,16 +629,17 @@ int connect(CONNECT_SIG)
#else
/* make sure we don't touch any standard outputs */
- if(__fd == STDIN_FILENO || __fd == STDOUT_FILENO || __fd == STDERR_FILENO)
+ if(__fd == STDIN_FILENO || __fd == STDOUT_FILENO || __fd == STDERR_FILENO){
+ if (realconnect == NULL) {
+ dwr("Unresolved symbol: connect(). Library is exiting.\n");
+ exit(-1);
+ }
return(realconnect(__fd, __addr, __len));
- int sock_type = -1;
- socklen_t sock_type_len = sizeof(sock_type);
+ }
+
struct sockaddr_in *connaddr;
connaddr = (struct sockaddr_in *) __addr;
- getsockopt(__fd, SOL_SOCKET, SO_TYPE,
- (void *) &sock_type, &sock_type_len);
-
if(__addr != NULL && (connaddr->sin_family == AF_LOCAL
|| connaddr->sin_family == PF_NETLINK
|| connaddr->sin_family == AF_NETLINK
@@ -624,13 +648,9 @@ int connect(CONNECT_SIG)
return err;
}
- char cmd[BUF_SZ];
- if (realconnect == NULL) {
- dwr("Unresolved symbol: connect()\n");
- return -1;
- }
-
/* assemble and route command */
+ int err;
+ char cmd[BUF_SZ];
memset(cmd, '\0', BUF_SZ);
struct connect_st rpc_st;
rpc_st.__tid = syscall(SYS_gettid);
@@ -778,7 +798,6 @@ int accept(ACCEPT_SIG)
#ifdef CHECKS
/* Check that this is a valid fd */
if(fcntl(sockfd, F_GETFD) < 0) {
- dwr("EBADF\n");
return -1;
errno = EBADF;
}
@@ -787,13 +806,11 @@ int accept(ACCEPT_SIG)
socklen_t sock_type_len = sizeof(sock_type);
if(getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len) < 0) {
errno = ENOTSOCK;
- dwr("ENOTSOCK\n");
return -1;
}
/* Check that this socket supports accept() */
if(!(sock_type && (SOCK_STREAM | SOCK_SEQPACKET))) {
errno = EOPNOTSUPP;
- dwr("EOPNOTSUPP\n");
return -1;
}
/* Check that we haven't hit the soft-limit file descriptors allowed */
@@ -801,7 +818,6 @@ int accept(ACCEPT_SIG)
getrlimit(RLIMIT_NOFILE, &rl);
if(sockfd >= rl.rlim_cur){
errno = EMFILE;
- dwr("EMFILE\n");
return -1;
}
#endif
@@ -822,16 +838,12 @@ int accept(ACCEPT_SIG)
return -1;
}
- char gmybuf[16];
- int new_conn_socket;
-
- char c[1];
- int n = read(sockfd, c, sizeof(c));
+ char gmybuf[16], c[1];
+ int new_conn_socket, n = read(sockfd, c, sizeof(c));
if(n > 0)
{
ssize_t size = sock_fd_read(fdret_sock, gmybuf, sizeof(gmybuf), &new_conn_socket);
- if(size > 0)
- {
+ if(size > 0) {
/* Send our local-fd number back to service so it can complete its mapping table */
memset(cmd, '\0', BUF_SZ);
cmd[0] = RPC_FD_MAP_COMPLETION;
@@ -869,9 +881,27 @@ int accept(ACCEPT_SIG)
listen() intercept function */
int listen(LISTEN_SIG)
{
+ #ifdef CHECKS
+ /* Check that this is a valid fd */
+ if(fcntl(sockfd, F_GETFD) < 0) {
+ return -1;
+ errno = EBADF;
+ }
+ /* Check that it is a socket */
+ int sock_type;
+ socklen_t sock_type_len = sizeof(sock_type);
+ if(getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len) < 0) {
+ errno = ENOTSOCK;
+ return -1;
+ }
+ /* Check that this socket supports accept() */
+ if(!(sock_type && (SOCK_STREAM | SOCK_SEQPACKET))) {
+ errno = EOPNOTSUPP;
+ return -1;
+ }
+ #endif
+
int err;
- /* FIXME: Check that this socket supports listen(), return EOPNOTSUPP */
- /* FIXME: Check that the provided fd is a socket, return ENOTSOCK */
#ifdef DUMMY
dwr("listen(%d)\n", sockfd);
diff --git a/netcon/libintercept.so.1.0 b/netcon/libintercept.so.1.0
index 1dc1f0da..106c8c20 100755
--- a/netcon/libintercept.so.1.0
+++ b/netcon/libintercept.so.1.0
Binary files differ