]> granicus.if.org Git - curl/commitdiff
David McCreedy added CURLOPT_SOCKOPTFUNCTION and CURLOPT_SOCKOPTDATA to
authorDaniel Stenberg <daniel@haxx.se>
Tue, 29 Aug 2006 14:39:33 +0000 (14:39 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 29 Aug 2006 14:39:33 +0000 (14:39 +0000)
allow applications to set their own socket options.

CHANGES
RELEASE-NOTES
docs/libcurl/curl_easy_setopt.3
include/curl/curl.h
include/curl/multi.h
lib/connect.c
lib/setup.h
lib/url.c
lib/urldata.h

diff --git a/CHANGES b/CHANGES
index ab0a8fd3e9e5f907f08927a1b0849809fb99d26b..f58c00ae7225752330f6d7cd65048d66d7ba72ab 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,10 @@
 
                                   Changelog
 
+Daniel (29 August 2006)
+- David McCreedy added CURLOPT_SOCKOPTFUNCTION and CURLOPT_SOCKOPTDATA to
+  allow applications to set their own socket options.
+
 Daniel (25 August 2006)
 - Armel Asselin reported that the 'running_handles' counter wasn't updated
   properly if you removed a "live" handle from a multi handle with
index cc014a2b32790b85912ec62c78d8217547de9203..70689cee662ae77836e1ae2486b23d0af94d5282 100644 (file)
@@ -3,7 +3,7 @@ Curl and libcurl 7.15.6
  Public curl release number:               96
  Releases counted from the very beginning: 123
  Available command line options:           114
- Available curl_easy_setopt() options:     133
+ Available curl_easy_setopt() options:     135
  Number of public functions in libcurl:    54
  Amount of public web site mirrors:        33
  Number of known libcurl bindings:         32
@@ -11,12 +11,13 @@ Curl and libcurl 7.15.6
 
 This release includes the following changes:
 
+ o CURLOPT_SOCKOPTFUNCTION and CURLOPT_SOCKOPTDATA were added
  o (FTP) libcurl avoids sending TYPE if the desired type was already set
  o (FTP) CURLOPT_PREQUOTE works even when CURLOPT_NOBODY is set true
 
 This release includes the following bugfixes:
 
- o running_handles' counter wasn't always updated properly when
+ o the 'running_handles' counter wasn't always updated properly when
    curl_multi_remove_handle() was used
  o (FTP) EPRT transfers with IPv6 didn't work properly
  o (FTP) SINGLECWD mode and using files in the root dir
index 0fce61a98d18cfa65d5d058a39c4914b3f3231bd..98abd417d12eb12d4d197da0f7032e8cf101a4e3 100644 (file)
@@ -160,12 +160,28 @@ found in \fI<curl/curl.h>\fP. This function gets called by libcurl when
 something special I/O-related needs to be done that the library can't do by
 itself. For now, rewinding the read data stream is the only action it can
 request. The rewinding of the read data stream may be necessary when doing a
-HTTP PUT or POST with a multi-pass authentication method.  (Opion added in
+HTTP PUT or POST with a multi-pass authentication method.  (Option added in
 7.12.3)
 .IP CURLOPT_IOCTLDATA
 Pass a pointer that will be untouched by libcurl and passed as the 3rd
 argument in the ioctl callback set with \fICURLOPT_IOCTLFUNCTION\fP.  (Option
 added in 7.12.3)
+.IP CURLOPT_SOCKOPTFUNCTION
+Function pointer that should match the \fIcurl_sockopt_callback\fP prototype
+found in \fI<curl/curl.h>\fP. This function gets called by libcurl after the
+socket() call but before the connect() call. The callback's \fIpurpose\fP
+argument identifies the exact purpose for this particular socket, and
+currently only one value is supported: \fICURLSOCKTYPE_IPCXN\fP for the
+primary connection (meaning the control connection in the FTP case). Future
+versions of libcurl may support more purposes. It passes the newly created
+socket descriptor so additional setsockopt() calls can be done at the user's
+discretion.  A non-zero return code from the callback function will signal an
+unrecoverable error to the library and it will close the socket and return
+\fICURLE_COULDNT_CONNECT\fP.  (Option added in 7.15.6.)
+.IP CURLOPT_SOCKOPTDATA
+Pass a pointer that will be untouched by libcurl and passed as the first
+argument in the sockopt callback set with \fICURLOPT_SOCKOPTFUNCTION\fP.
+(Option added in 7.15.6.)
 .IP CURLOPT_PROGRESSFUNCTION
 Function pointer that should match the \fIcurl_progress_callback\fP prototype
 found in \fI<curl/curl.h>\fP. This function gets called by libcurl instead of
index f4166cb58f485208deae9afb9a496688617393e7..6f0be2c9f2801be698760b25b18cfd50c833e72f 100644 (file)
@@ -133,6 +133,47 @@ extern "C" {
 #undef FILESIZEBITS
 #endif
 
+#if defined(_WIN32) && !defined(WIN32)
+/* Chris Lewis mentioned that he doesn't get WIN32 defined, only _WIN32 so we
+   make this adjustment to catch this. */
+#define WIN32 1
+#endif
+
+#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \
+  !defined(__CYGWIN__) || defined(__MINGW32__)
+#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H))
+/* The check above prevents the winsock2 inclusion if winsock.h already was
+   included, since they can't co-exist without problems */
+#include <winsock2.h>
+#endif
+#else
+
+/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
+   libc5-based Linux systems. Only include it on system that are known to
+   require it! */
+#if defined(_AIX) || defined(NETWARE) || defined(__NetBSD__) || defined(__minix)
+#include <sys/select.h>
+#endif
+
+#ifndef _WIN32_WCE
+#include <sys/socket.h>
+#endif
+#include <sys/time.h>
+#include <sys/types.h>
+#endif
+
+#ifndef curl_socket_typedef
+/* socket typedef */
+#ifdef WIN32
+typedef SOCKET curl_socket_t;
+#define CURL_SOCKET_BAD INVALID_SOCKET
+#else
+typedef int curl_socket_t;
+#define CURL_SOCKET_BAD -1
+#endif
+#define curl_socket_typedef
+#endif /* curl_socket_typedef */
+
 struct curl_httppost {
   struct curl_httppost *next;       /* next entry in the list */
   char *name;                       /* pointer to allocated name */
@@ -184,6 +225,14 @@ typedef size_t (*curl_read_callback)(char *buffer,
                                       size_t nitems,
                                       void *instream);
 
+typedef enum  {
+  CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */
+  CURLSOCKTYPE_LAST   /* never use */
+} curlsocktype;
+
+typedef int (*curl_sockopt_callback)(void *clientp,
+                                     curl_socket_t curlfd,
+                                     curlsocktype purpose);
 
 #ifndef CURL_NO_OLDIES
   /* not used since 7.10.8, will be removed in a future release */
@@ -982,6 +1031,10 @@ typedef enum {
   /* Pointer to command string to send if USER/PASS fails. */
   CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147),
 
+  /* callback function for setting socket options */
+  CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
+  CINIT(SOCKOPTDATA, OBJECTPOINT, 149),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
index 6811ce798d3e4a16ce8dd48ffdab5a72c0a7de4b..1beda8a922753984c6e96c4c909017fdd91a86db 100644 (file)
     file descriptors simultaneous easily.
 
 */
-#if defined(_WIN32) && !defined(WIN32)
-/* Chris Lewis mentioned that he doesn't get WIN32 defined, only _WIN32 so we
-   make this adjustment to catch this. */
-#define WIN32 1
-#endif
-
-#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \
-  !defined(__CYGWIN__) || defined(__MINGW32__)
-#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H))
-/* The check above prevents the winsock2 inclusion if winsock.h already was
-   included, since they can't co-exist without problems */
-#include <winsock2.h>
-#endif
-#else
-
-/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
-   libc5-based Linux systems. Only include it on system that are known to
-   require it! */
-#if defined(_AIX) || defined(NETWARE) || defined(__NetBSD__) || defined(__minix)
-#include <sys/select.h>
-#endif
-
-#ifndef _WIN32_WCE
-#include <sys/socket.h>
-#endif
-#include <sys/time.h>
-#include <sys/types.h>
-#endif
 
 /*
  * This header file should not really need to include "curl.h" since curl.h
@@ -83,18 +55,6 @@ extern "C" {
 
 typedef void CURLM;
 
-#ifndef curl_socket_typedef
-/* Public socket typedef */
-#ifdef WIN32
-typedef SOCKET curl_socket_t;
-#define CURL_SOCKET_BAD INVALID_SOCKET
-#else
-typedef int curl_socket_t;
-#define CURL_SOCKET_BAD -1
-#endif
-#define curl_socket_typedef
-#endif /* curl_socket_typedef */
-
 typedef enum {
   CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
                                     curl_multi_socket*() soon */
index 95fdf8119a1d10c0252f18f76d631306030744a5..4e7f4f8ea1ac243d1d807ce49b70f936b707df24 100644 (file)
@@ -702,6 +702,17 @@ singleipconnect(struct connectdata *conn,
 
   nosigpipe(conn, sockfd);
 
+  if(data->set.fsockopt) {
+    /* activate callback for setting socket options */
+    error = data->set.fsockopt(data->set.sockopt_client,
+                               sockfd,
+                               CURLSOCKTYPE_IPCXN);
+    if (error) {
+      sclose(sockfd); /* close the socket and bail out */
+      return CURL_SOCKET_BAD;
+    }
+  }
+
   /* possibly bind the local end to an IP, interface or port */
   res = bindlocal(conn, sockfd);
   if(res) {
index 3538256c4b6780ba83eceee3e1e807eaae7920a7..1e64c928a031845cc51f1617bd38a188c021b34b 100644 (file)
@@ -278,19 +278,6 @@ int fileno( FILE *stream);
 
 #endif /* WIN32 */
 
-#ifndef curl_socket_typedef
-/* now typedef our socket type */
-#ifdef WIN32
-typedef SOCKET curl_socket_t;
-#define CURL_SOCKET_BAD INVALID_SOCKET
-#else
-typedef int curl_socket_t;
-#define CURL_SOCKET_BAD -1
-#endif
-#define curl_socket_typedef
-#endif /* curl_socket_typedef */
-
-
 #if defined(WIN32) && !defined(__CYGWIN__) && !defined(USE_ARES) && \
     !defined(__LCC__)  /* lcc-win32 doesn't have _beginthreadex() */
 #ifdef ENABLE_IPV6
index c0641c78b801dc84194c45517a692ac72c5e66d9..17f543615340e0e547bd203e47b6f714ac362565 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -1551,6 +1551,20 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
     data->set.ftp_alternative_to_user = va_arg(param, char *);
     break;
 
+  case CURLOPT_SOCKOPTFUNCTION:
+    /*
+     * socket callback function: called after socket() but before connect()
+     */
+    data->set.fsockopt = va_arg(param, curl_sockopt_callback);
+    break;
+
+  case CURLOPT_SOCKOPTDATA:
+    /*
+     * socket callback data pointer. Might be NULL.
+     */
+    data->set.sockopt_client = va_arg(param, void *);
+    break;
+
   default:
     /* unknown tag and its companion, just ignore: */
     result = CURLE_FAILED_INIT; /* correct this */
index 33f7ee860201d3fd1190cdd655ae21d5fb7f104f..5acac2c536ce1745f93f37561db21f5123b1606d 100644 (file)
@@ -1029,6 +1029,8 @@ struct UserDefined {
   curl_progress_callback fprogress;  /* function for progress information */
   curl_debug_callback fdebug;      /* function that write informational data */
   curl_ioctl_callback ioctl;       /* function for I/O control */
+  curl_sockopt_callback fsockopt;  /* function for setting socket options */
+  void *sockopt_client; /* pointer to pass to the socket options callback */
 
   /* the 3 curl_conv_callback functions below are used on non-ASCII hosts */
   /* function to convert from the network encoding: */