Function pointer that should match the \fIcurl_opensocket_callback\fP
prototype found in \fI<curl/curl.h>\fP. This function gets called by libcurl
instead of the \fIsocket(2)\fP 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 resolved peer address as a
+identifies the exact purpose for this particular socket:
+\fICURLSOCKTYPE_IPCXN\fP is for IP based connections. Future versions of
+libcurl may support more purposes. It passes the resolved peer address as a
\fIaddress\fP argument so the callback can modify the address or refuse to
connect at all. The callback function should return the socket or
\fICURL_SOCKET_BAD\fP in case no connection should be established or any error
/*
* Create a socket based on info from 'conn' and 'ai'.
*
- * Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open
- * socket callback is set, used that!
+ * 'addr' should be a pointer to the correct struct to get data back, or NULL.
+ * 'sockfd' must be a pointer to a socket descriptor.
+ *
+ * If the open socket callback is set, used that!
*
*/
CURLcode Curl_socket(struct connectdata *conn,
curl_socket_t *sockfd)
{
struct SessionHandle *data = conn->data;
-#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
- struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
-#endif
+ struct Curl_sockaddr_ex dummy;
+
+ if(!addr)
+ /* if the caller doesn't want info back, use a local temp copy */
+ addr = &dummy;
/*
* The Curl_sockaddr_ex structure is basically libcurl's external API
return CURLE_FAILED_INIT;
#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
- if(conn->scope && (addr->family == AF_INET6))
+ if(conn->scope && (addr->family == AF_INET6)) {
+ struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
sa6->sin6_scope_id = conn->scope;
+ }
#endif
return CURLE_OK;
portsock = CURL_SOCKET_BAD;
error = 0;
for(ai = res; ai; ai = ai->ai_next) {
- /*
- * Workaround for AIX5 getaddrinfo() problem (it doesn't set ai_socktype):
- */
- if(ai->ai_socktype == 0)
- ai->ai_socktype = conn->socktype;
-
- portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- if(portsock == CURL_SOCKET_BAD) {
+ result = Curl_socket(conn, ai, NULL, &portsock);
+ if(result) {
error = SOCKERRNO;
continue;
}
<datacheck>
[OPEN] counter: 1
[OPEN] counter: 2
-moo
[CLOSE] counter: 2
+moo
[CLOSE] counter: 1
+[CLOSE] counter: 0
</datacheck>
</reply>
#
# Verify data after the test has been "shot"
<verify>
+<strippart>
+s/^(EPRT \|1\|)(.*)/$1/
+</strippart>
<protocol>
USER anonymous\r
PASS ftp@example.com\r
PWD\r
-EPSV\r
+EPRT |1|
TYPE I\r
SIZE 596\r
RETR 596\r