ws2_32: Ignore lpFrom for connected sockets.
If the the socket is connected and lpFrom is not NULL, Linux will set msg_namelen to zero and ignore msg_name in recvfrom so don't try try to update lpFrom.
This commit is contained in:
parent
5b7bec34c1
commit
30e6b81dd1
|
@ -1103,7 +1103,17 @@ static int WS2_recv( int fd, struct iovec* iov, int count,
|
||||||
if ( (n = recvmsg(fd, &hdr, *lpFlags)) == -1 )
|
if ( (n = recvmsg(fd, &hdr, *lpFlags)) == -1 )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ( lpFrom &&
|
/* if this socket is connected and lpFrom is not NULL, Linux doesn't give us
|
||||||
|
* msg_name and msg_namelen from recvmsg, but it does set msg_namelen to zero.
|
||||||
|
*
|
||||||
|
* quoting linux 2.6 net/ipv4/tcp.c:
|
||||||
|
* "According to UNIX98, msg_name/msg_namelen are ignored
|
||||||
|
* on connected socket. I was just happy when found this 8) --ANK"
|
||||||
|
*
|
||||||
|
* likewise MSDN says that lpFrom and lpFromlen are ignored for
|
||||||
|
* connection-oriented sockets, so don't try to update lpFrom.
|
||||||
|
*/
|
||||||
|
if ( lpFrom && hdr.msg_namelen &&
|
||||||
ws_sockaddr_u2ws( &unix_sockaddr.addr, lpFrom, lpFromlen ) != 0 )
|
ws_sockaddr_u2ws( &unix_sockaddr.addr, lpFrom, lpFromlen ) != 0 )
|
||||||
{
|
{
|
||||||
/* The from buffer was too small, but we read the data
|
/* The from buffer was too small, but we read the data
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include <winerror.h>
|
#include <winerror.h>
|
||||||
|
|
||||||
#define MAX_CLIENTS 4 /* Max number of clients */
|
#define MAX_CLIENTS 4 /* Max number of clients */
|
||||||
#define NUM_TESTS 3 /* Number of tests performed */
|
#define NUM_TESTS 4 /* Number of tests performed */
|
||||||
#define FIRST_CHAR 'A' /* First character in transferred pattern */
|
#define FIRST_CHAR 'A' /* First character in transferred pattern */
|
||||||
#define BIND_SLEEP 10 /* seconds to wait between attempts to bind() */
|
#define BIND_SLEEP 10 /* seconds to wait between attempts to bind() */
|
||||||
#define BIND_TRIES 6 /* Number of bind() attempts */
|
#define BIND_TRIES 6 /* Number of bind() attempts */
|
||||||
|
@ -269,6 +269,16 @@ static int do_synchronous_recv ( SOCKET s, char *buf, int buflen, int recvlen )
|
||||||
return p - buf;
|
return p - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int do_synchronous_recvfrom ( SOCKET s, char *buf, int buflen,int flags,struct sockaddr *from, socklen_t *fromlen, int recvlen )
|
||||||
|
{
|
||||||
|
char* last = buf + buflen, *p;
|
||||||
|
int n = 1;
|
||||||
|
for ( p = buf; n > 0 && p < last; p += n )
|
||||||
|
n = recvfrom ( s, p, min ( recvlen, last - p ), 0, from, fromlen );
|
||||||
|
wsa_ok ( n, 0 <=, "do_synchronous_recv (%x): error %d:\n" );
|
||||||
|
return p - buf;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call this routine right after thread startup.
|
* Call this routine right after thread startup.
|
||||||
* SO_OPENTYPE must by 0, regardless what the server did.
|
* SO_OPENTYPE must by 0, regardless what the server did.
|
||||||
|
@ -626,6 +636,76 @@ static VOID WINAPI simple_client ( client_params *par )
|
||||||
client_stop ();
|
client_stop ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* simple_mixed_client: mixing send and recvfrom
|
||||||
|
*/
|
||||||
|
static VOID WINAPI simple_mixed_client ( client_params *par )
|
||||||
|
{
|
||||||
|
test_params *gen = par->general;
|
||||||
|
client_memory *mem;
|
||||||
|
int n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id;
|
||||||
|
char *p;
|
||||||
|
socklen_t fromLen = sizeof(mem->addr);
|
||||||
|
struct sockaddr test;
|
||||||
|
|
||||||
|
id = GetCurrentThreadId();
|
||||||
|
trace ( "simple_client (%x): starting\n", id );
|
||||||
|
/* wait here because we want to call set_so_opentype before creating a socket */
|
||||||
|
WaitForSingleObject ( server_ready, INFINITE );
|
||||||
|
trace ( "simple_client (%x): server ready\n", id );
|
||||||
|
|
||||||
|
check_so_opentype ();
|
||||||
|
set_so_opentype ( FALSE ); /* non-overlapped */
|
||||||
|
client_start ( par );
|
||||||
|
mem = TlsGetValue ( tls );
|
||||||
|
|
||||||
|
/* Connect */
|
||||||
|
wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ),
|
||||||
|
0 ==, "simple_client (%x): connect error: %d\n" );
|
||||||
|
ok ( set_blocking ( mem->s, TRUE ) == 0,
|
||||||
|
"simple_client (%x): failed to set blocking mode\n", id );
|
||||||
|
trace ( "simple_client (%x) connected\n", id );
|
||||||
|
|
||||||
|
/* send data to server */
|
||||||
|
n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, par->buflen );
|
||||||
|
ok ( n_sent == n_expected,
|
||||||
|
"simple_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
|
||||||
|
|
||||||
|
/* shutdown send direction */
|
||||||
|
wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%x): shutdown failed: %d\n" );
|
||||||
|
|
||||||
|
/* this shouldn't change, since lpFrom, is not updated on
|
||||||
|
connection oriented sockets - exposed by bug 11640
|
||||||
|
*/
|
||||||
|
((struct sockaddr_in*)&test)->sin_addr.s_addr = inet_addr("0.0.0.0");
|
||||||
|
|
||||||
|
/* Receive data echoed back & check it */
|
||||||
|
n_recvd = do_synchronous_recvfrom ( mem->s,
|
||||||
|
mem->recv_buf,
|
||||||
|
n_expected,
|
||||||
|
0,
|
||||||
|
(struct sockaddr *)&test,
|
||||||
|
&fromLen,
|
||||||
|
par->buflen );
|
||||||
|
ok ( n_recvd == n_expected,
|
||||||
|
"simple_client (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
|
||||||
|
|
||||||
|
/* check that lpFrom was not updated */
|
||||||
|
ok(0 ==
|
||||||
|
strcmp(
|
||||||
|
inet_ntoa(((struct sockaddr_in*)&test)->sin_addr),
|
||||||
|
"0.0.0.0"), "lpFrom shouldn't be updated on connection oriented sockets\n");
|
||||||
|
|
||||||
|
/* check data */
|
||||||
|
p = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
|
||||||
|
ok ( p == NULL, "simple_client (%x): test pattern error: %d\n", id, p - mem->recv_buf);
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
read_zero_bytes ( mem->s );
|
||||||
|
trace ( "simple_client (%x) exiting\n", id );
|
||||||
|
client_stop ();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* event_client: An event-driven client
|
* event_client: An event-driven client
|
||||||
*/
|
*/
|
||||||
|
@ -1013,6 +1093,27 @@ static test_setup tests [NUM_TESTS] =
|
||||||
0,
|
0,
|
||||||
128
|
128
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
/* Test 3: synchronous mixed client and server */
|
||||||
|
{
|
||||||
|
{
|
||||||
|
STD_STREAM_SOCKET,
|
||||||
|
2048,
|
||||||
|
16,
|
||||||
|
2
|
||||||
|
},
|
||||||
|
simple_server,
|
||||||
|
{
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
64
|
||||||
|
},
|
||||||
|
simple_mixed_client,
|
||||||
|
{
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
128
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue