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
 													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,
 													this case, and does not require these constants to have the same value,
 													so a portable application should check for both possibilities.
 													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.
 	[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).
 	[ ] EINVAL - Socket is not listening for connections, or addrlen is invalid (e.g., is negative).
 	[ ] EINVAL - (accept4()) invalid value in flags.
 	[ ] 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.
 	[ ] 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
 	[ ] 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.
 												limited by the socket buffer limits, not by the system memory.
 	[i] ENOTSOCK - The descriptor references a file, not a socket.
 	[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.
 	[ ] 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);
 				l->tap->send_return_value(l->conn, -1, EISCONN);
 				break;
 				break;
 			case ERR_ABRT:
 			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;
 				break;
 
 
 				// FIXME: Below are errors which don't have a standard errno correlate
 				// 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"
 #include "common.h"
 
 
 #ifdef CHECKS
 #ifdef CHECKS
+  //#include <sys/time.h>
+  #include <sys/resource.h>
   #include <linux/net.h> /* for NPROTO */
   #include <linux/net.h> /* for NPROTO */
 
 
   #define SOCK_MAX (SOCK_PACKET + 1)
   #define SOCK_MAX (SOCK_PACKET + 1)
@@ -763,6 +765,30 @@ int accept4(ACCEPT4_SIG)
    accept() intercept function */
    accept() intercept function */
 int accept(ACCEPT_SIG)
 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
 #ifdef DUMMY
     return realaccept(sockfd, addr, addrlen);
     return realaccept(sockfd, addr, addrlen);
 #else
 #else
@@ -770,17 +796,9 @@ int accept(ACCEPT_SIG)
   if(sockfd == STDIN_FILENO || sockfd == STDOUT_FILENO || sockfd == STDERR_FILENO)
   if(sockfd == STDIN_FILENO || sockfd == STDOUT_FILENO || sockfd == STDERR_FILENO)
     return(realaccept(sockfd, addr, addrlen));
     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;
   addr->sa_family = AF_INET;
   /* TODO: also get address info */
   /* TODO: also get address info */
 
 
-  /* FIXME: Check that socket is type SOCK_STREAM */
-
   char cmd[BUF_SZ];
   char cmd[BUF_SZ];
   if(realaccept == NULL) {
   if(realaccept == NULL) {
     dwr( "Unresolved symbol: accept()\n");
     dwr( "Unresolved symbol: accept()\n");

BIN
netcon/libintercept.so.1.0