Browse Source

EBADF, EOPNOTSUPP, EMFILE error repoarting for accept()

Joseph Henry 9 years ago
parent
commit
8a05efa365
3 changed files with 32 additions and 14 deletions
  1. 6 6
      netcon/NetconEthernetTap.cpp
  2. 26 8
      netcon/intercept.c
  3. BIN
      netcon/libintercept.so.1.0

+ 6 - 6
netcon/NetconEthernetTap.cpp

@@ -494,18 +494,18 @@ int NetconEthernetTap::send_return_value(int fd, int retval, int _errno = 0)
 													to be accepted. POSIX.1-2001 allows either error to be returned for
 													this case, and does not require these constants to have the same value,
 													so a portable application should check for both possibilities.
-	[ ] EBADF - The descriptor is invalid.
-	[i] ECONNABORTED - A connection has been aborted.
+	[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).
 	[ ] EINVAL - Socket is not listening for connections, or addrlen is invalid (e.g., is negative).
 	[ ] EINVAL - (accept4()) invalid value in flags.
-	[ ] EMFILE - The per-process limit of open file descriptors has been reached.
+	[I] EMFILE - The per-process limit of open file descriptors has been reached.
 	[ ] ENFILE - The system limit on the total number of open files has been reached.
 	[ ] ENOBUFS, ENOMEM - Not enough free memory. This often means that the memory allocation is
 												limited by the socket buffer limits, not by the system memory.
 	[i] ENOTSOCK - The descriptor references a file, not a socket.
-	[i] EOPNOTSUPP - The referenced socket is not of type SOCK_STREAM.
+	[I] EOPNOTSUPP - The referenced socket is not of type SOCK_STREAM.
 	[ ] EPROTO - Protocol error.
 
  *
@@ -675,8 +675,8 @@ void NetconEthernetTap::nc_err(void *arg, err_t err)
 				l->tap->send_return_value(l->conn, -1, EISCONN);
 				break;
 			case ERR_ABRT:
-				fprintf(stderr, "nc_err(): ERR_ABRT->ETIMEDOUT\n"); // FIXME: Correct?
-				l->tap->send_return_value(l->conn, -1, ETIMEDOUT);
+				fprintf(stderr, "nc_err(): ERR_ABRT->ECONNREFUSED\n");
+				l->tap->send_return_value(l->conn, -1, ECONNREFUSED);
 				break;
 
 				// FIXME: Below are errors which don't have a standard errno correlate

+ 26 - 8
netcon/intercept.c

@@ -73,6 +73,8 @@ char *progname = "";
 #include "common.h"
 
 #ifdef CHECKS
+  //#include <sys/time.h>
+  #include <sys/resource.h>
   #include <linux/net.h> /* for NPROTO */
 
   #define SOCK_MAX (SOCK_PACKET + 1)
@@ -763,6 +765,30 @@ int accept4(ACCEPT4_SIG)
    accept() intercept function */
 int accept(ACCEPT_SIG)
 {
+#ifdef CHECKS
+  /* Check that this is a valid fd */
+  if(fcntl(sockfd, F_GETFD) < 0) {
+    return -1;
+    errno = EBADF;
+  }
+  int sock_type = -1;
+  socklen_t sock_type_len = sizeof(sock_type);
+  getsockopt(sockfd, SOL_SOCKET, SO_TYPE,
+       (void *) &sock_type, &sock_type_len);
+  /* Check that this socket supports accept() */
+  if(!(sock_type & (SOCK_STREAM | SOCK_SEQPACKET))) {
+    errno = EOPNOTSUPP;
+    return -1;
+  }
+  /* Check that we haven't hit the soft-limit file descriptors allowed */
+  struct rlimit rl;
+  getrlimit(RLIMIT_NOFILE, &rl);
+  if(sockfd >= rl.rlim_cur){
+    errno = EMFILE;
+    return -1;
+  }
+#endif
+
 #ifdef DUMMY
     return realaccept(sockfd, addr, addrlen);
 #else
@@ -770,17 +796,9 @@ int accept(ACCEPT_SIG)
   if(sockfd == STDIN_FILENO || sockfd == STDOUT_FILENO || sockfd == STDERR_FILENO)
     return(realaccept(sockfd, addr, addrlen));
 
-  int sock_type = -1;
-  socklen_t sock_type_len = sizeof(sock_type);
-
-  getsockopt(sockfd, SOL_SOCKET, SO_TYPE,
-       (void *) &sock_type, &sock_type_len);
-
   addr->sa_family = AF_INET;
   /* TODO: also get address info */
 
-  /* FIXME: Check that socket is type SOCK_STREAM */
-
   char cmd[BUF_SZ];
   if(realaccept == NULL) {
     dwr( "Unresolved symbol: accept()\n");

BIN
netcon/libintercept.so.1.0