Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- These functions are incredibly slow on Windows. To avoid timeouts, I had to put the tests in protocol.c rather than the crowded sock.c. --- configure.ac | 1 - dlls/ws2_32/socket.c | 339 ++++++++++++++++++++++++--------- dlls/ws2_32/tests/protocol.c | 359 +++++++++++++++++++++++++++++++++++ dlls/ws2_32/tests/sock.c | 66 ------- 4 files changed, 609 insertions(+), 156 deletions(-)
diff --git a/configure.ac b/configure.ac index dea25b0c3f..2ad8552de7 100644 --- a/configure.ac +++ b/configure.ac @@ -2241,7 +2241,6 @@ AC_CHECK_FUNCS(\ getaddrinfo \ getnameinfo \ getnetbyname \ - getservbyport \ )
dnl Check for clock_gettime which may be in -lrt diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index eb21e4b4b3..2713be675a 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -649,7 +649,7 @@ static FARPROC blocking_hook = (FARPROC)WSA_DefaultBlockingHook; static struct WS_hostent *WS_create_he(char *name, int aliases, int aliases_size, int addresses, int address_length); static struct WS_hostent *WS_dup_he(const struct hostent* p_he); static struct WS_protoent *WS_create_pe( const char *name, char **aliases, int prot ); -static struct WS_servent *WS_dup_se(const struct servent* p_se); +static struct WS_servent *WS_create_se( const char *name, char **aliases, int port, const char *proto ); static int ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, int *size);
int WSAIOCTL_GetInterfaceCount(void); @@ -1488,20 +1488,6 @@ static int convert_sockopt(INT *level, INT *optname)
/* ----------------------------------- Per-thread info (or per-process?) */
-static char *strdup_lower(const char *str) -{ - int i; - char *ret = HeapAlloc( GetProcessHeap(), 0, strlen(str) + 1 ); - - if (ret) - { - for (i = 0; str[i]; i++) ret[i] = tolower(str[i]); - ret[i] = 0; - } - else SetLastError(WSAENOBUFS); - return ret; -} - /* Utility: get the SO_RCVTIMEO or SO_SNDTIMEO socket option * from an fd and return the value converted to milli seconds * or 0 if there is an infinite time out */ @@ -6560,41 +6546,258 @@ struct WS_protoent* WINAPI WS_getprotobynumber(int number) }
+static const struct +{ + unsigned short port; + const char *names[3]; + const char *protos[2]; +} +services[] = +{ + { 7, {"echo"}, {"tcp", "udp"} }, + { 9, {"discard", "sink"}, {"tcp", "udp"} }, + { 11, {"systat", "users"}, {"tcp", "udp"} }, + { 13, {"daytime"}, {"tcp", "udp"} }, + { 17, {"qotd", "quote"}, {"tcp", "udp"} }, + { 19, {"chargen", "ttytst"}, {"tcp", "udp"} }, + { 20, {"ftp-data"}, {"tcp"} }, + { 21, {"ftp"}, {"tcp"} }, + { 22, {"ssh"}, {"tcp"} }, + { 23, {"telnet"}, {"tcp"} }, + { 25, {"smtp", "mail"}, {"tcp"} }, + { 37, {"time", "timserver"}, {"tcp", "udp"} }, + { 39, {"rlp", "resource"}, {"udp"} }, + { 42, {"nameserver", "name"}, {"tcp", "udp"} }, + { 43, {"nicname", "whois"}, {"tcp"} }, + { 53, {"domain"}, {"tcp", "udp"} }, + { 67, {"bootps", "dhcps"}, {"udp"} }, + { 68, {"bootpc", "dhcpc"}, {"udp"} }, + { 69, {"tftp"}, {"udp"} }, + { 70, {"gopher"}, {"tcp"} }, + { 79, {"finger"}, {"tcp"} }, + { 80, {"http", "www"}, {"tcp"} }, + { 81, {"hosts2-ns"}, {"tcp", "udp"} }, + { 88, {"kerberos", "krb5"}, {"tcp", "udp"} }, + { 101, {"hostname", "hostnames"}, {"tcp"} }, + { 102, {"iso-tsap"}, {"tcp"} }, + { 107, {"rtelnet"}, {"tcp"} }, + { 109, {"pop2", "postoffice"}, {"tcp"} }, + { 110, {"pop3"}, {"tcp"} }, + { 111, {"sunrpc", "rpcbind"}, {"tcp", "udp"} }, + { 113, {"auth", "ident"}, {"tcp"} }, + { 117, {"uucp-path"}, {"tcp"} }, + { 118, {"sqlserv"}, {"tcp"} }, + { 119, {"nntp", "usenet"}, {"tcp"} }, + { 123, {"ntp"}, {"udp"} }, + { 135, {"epmap", "loc-srv"}, {"tcp", "udp"} }, + { 137, {"netbios-ns", "nbname"}, {"tcp", "udp"} }, + { 138, {"netbios-dgm", "nbdatagram"}, {"udp"} }, + { 139, {"netbios-ssn", "nbsession"}, {"tcp"} }, + { 143, {"imap", "imap4"}, {"tcp"} }, + { 150, {"sql-net"}, {"tcp"} }, + { 156, {"sqlsrv"}, {"tcp"} }, + { 158, {"pcmail-srv"}, {"tcp"} }, + { 161, {"snmp"}, {"udp"} }, + { 162, {"snmptrap", "snmp-trap"}, {"udp"} }, + { 170, {"print-srv"}, {"tcp"} }, + { 179, {"bgp"}, {"tcp"} }, + { 194, {"irc"}, {"tcp"} }, + { 213, {"ipx"}, {"udp"} }, + { 322, {"rtsps"}, {"tcp", "udp"} }, + { 349, {"mftp"}, {"tcp", "udp"} }, + { 389, {"ldap"}, {"tcp"} }, + { 443, {"https", "MCom"}, {"tcp", "udp"} }, + { 445, {"microsoft-ds"}, {"tcp", "udp"} }, + { 464, {"kpasswd"}, {"tcp", "udp"} }, + { 500, {"isakmp", "ike"}, {"udp"} }, + { 507, {"crs"}, {"tcp", "udp"} }, + { 512, {"exec"}, {"tcp"} }, + { 512, {"biff", "comsat"}, {"udp", "tcp"} }, + { 513, {"login"}, {"tcp"} }, + { 513, {"who", "whod"}, {"udp", "tcp"} }, + { 514, {"cmd", "shell"}, {"tcp"} }, + { 514, {"syslog"}, {"udp", "tcp"} }, + { 515, {"printer", "spooler"}, {"tcp"} }, + { 517, {"talk"}, {"udp"} }, + { 518, {"ntalk"}, {"udp"} }, + { 520, {"efs"}, {"tcp"} }, + { 520, {"router", "route"}, {"udp", "tcp"} }, + { 522, {"ulp"}, {"tcp", "udp"} }, + { 525, {"timed", "timeserver"}, {"udp"} }, + { 526, {"tempo", "newdate"}, {"tcp"} }, + { 529, {"irc-serv"}, {"tcp", "udp"} }, + { 530, {"courier", "rpc"}, {"tcp"} }, + { 531, {"conference", "chat"}, {"tcp"} }, + { 532, {"netnews", "readnews"}, {"tcp"} }, + { 533, {"netwall"}, {"udp"} }, + { 540, {"uucp", "uucpd"}, {"tcp"} }, + { 543, {"klogin"}, {"tcp"} }, + { 544, {"kshell", "krcmd"}, {"tcp"} }, + { 546, {"dhcpv6-client"}, {"tcp", "udp"} }, + { 547, {"dhcpv6-server"}, {"tcp", "udp"} }, + { 548, {"afpovertcp"}, {"tcp", "udp"} }, + { 550, {"new-rwho", "new-who"}, {"udp"} }, + { 554, {"rtsp"}, {"tcp", "udp"} }, + { 556, {"remotefs", "rfs"}, {"tcp"} }, + { 560, {"rmonitor", "rmonitord"}, {"udp"} }, + { 561, {"monitor"}, {"udp"} }, + { 563, {"nntps", "snntp"}, {"tcp", "udp"} }, + { 565, {"whoami"}, {"tcp", "udp"} }, + { 568, {"ms-shuttle"}, {"tcp", "udp"} }, + { 569, {"ms-rome"}, {"tcp", "udp"} }, + { 593, {"http-rpc-epmap"}, {"tcp", "udp"} }, + { 612, {"hmmp-ind"}, {"tcp", "udp"} }, + { 613, {"hmmp-op"}, {"tcp", "udp"} }, + { 636, {"ldaps", "sldap"}, {"tcp"} }, + { 666, {"doom"}, {"tcp", "udp"} }, + { 691, {"msexch-routing"}, {"tcp", "udp"} }, + { 749, {"kerberos-adm"}, {"tcp", "udp"} }, + { 750, {"kerberos-iv"}, {"udp"} }, + { 800, {"mdbs_daemon"}, {"tcp", "udp"} }, + { 989, {"ftps-data"}, {"tcp"} }, + { 990, {"ftps"}, {"tcp"} }, + { 992, {"telnets"}, {"tcp"} }, + { 993, {"imaps"}, {"tcp"} }, + { 994, {"ircs"}, {"tcp"} }, + { 995, {"pop3s", "spop3"}, {"tcp", "udp"} }, + { 1034, {"activesync"}, {"tcp"} }, + { 1109, {"kpop"}, {"tcp"} }, + { 1110, {"nfsd-status"}, {"tcp"} }, + { 1110, {"nfsd-keepalive"}, {"udp"} }, + { 1155, {"nfa"}, {"tcp", "udp"} }, + { 1167, {"phone"}, {"udp"} }, + { 1270, {"opsmgr"}, {"tcp", "udp"} }, + { 1433, {"ms-sql-s"}, {"tcp", "udp"} }, + { 1434, {"ms-sql-m"}, {"tcp", "udp"} }, + { 1477, {"ms-sna-server"}, {"tcp", "udp"} }, + { 1478, {"ms-sna-base"}, {"tcp", "udp"} }, + { 1512, {"wins"}, {"tcp", "udp"} }, + { 1524, {"ingreslock", "ingres"}, {"tcp"} }, + { 1607, {"stt"}, {"tcp", "udp"} }, + { 1701, {"l2tp"}, {"udp"} }, + { 1711, {"pptconference"}, {"tcp", "udp"} }, + { 1723, {"pptp"}, {"tcp"} }, + { 1731, {"msiccp"}, {"tcp", "udp"} }, + { 1745, {"remote-winsock"}, {"tcp", "udp"} }, + { 1755, {"ms-streaming"}, {"tcp", "udp"} }, + { 1801, {"msmq"}, {"tcp", "udp"} }, + { 1812, {"radius"}, {"udp"} }, + { 1813, {"radacct"}, {"udp"} }, + { 1863, {"msnp"}, {"tcp", "udp"} }, + { 1900, {"ssdp"}, {"tcp", "udp"} }, + { 1944, {"close-combat"}, {"tcp", "udp"} }, + { 2049, {"nfsd", "nfs"}, {"udp"} }, + { 2053, {"knetd"}, {"tcp"} }, + { 2106, {"mzap"}, {"tcp", "udp"} }, + { 2177, {"qwave"}, {"tcp", "udp"} }, + { 2234, {"directplay"}, {"tcp", "udp"} }, + { 2382, {"ms-olap3"}, {"tcp", "udp"} }, + { 2383, {"ms-olap4"}, {"tcp", "udp"} }, + { 2393, {"ms-olap1"}, {"tcp", "udp"} }, + { 2394, {"ms-olap2"}, {"tcp", "udp"} }, + { 2460, {"ms-theater"}, {"tcp", "udp"} }, + { 2504, {"wlbs"}, {"tcp", "udp"} }, + { 2525, {"ms-v-worlds"}, {"tcp", "udp"} }, + { 2701, {"sms-rcinfo"}, {"tcp", "udp"} }, + { 2702, {"sms-xfer"}, {"tcp", "udp"} }, + { 2703, {"sms-chat"}, {"tcp", "udp"} }, + { 2704, {"sms-remctrl"}, {"tcp", "udp"} }, + { 2725, {"msolap-ptp2"}, {"tcp", "udp"} }, + { 2869, {"icslap"}, {"tcp", "udp"} }, + { 3020, {"cifs"}, {"tcp", "udp"} }, + { 3074, {"xbox"}, {"tcp", "udp"} }, + { 3126, {"ms-dotnetster"}, {"tcp", "udp"} }, + { 3132, {"ms-rule-engine"}, {"tcp", "udp"} }, + { 3268, {"msft-gc"}, {"tcp", "udp"} }, + { 3269, {"msft-gc-ssl"}, {"tcp", "udp"} }, + { 3343, {"ms-cluster-net"}, {"tcp", "udp"} }, + { 3389, {"ms-wbt-server"}, {"tcp", "udp"} }, + { 3535, {"ms-la"}, {"tcp", "udp"} }, + { 3540, {"pnrp-port"}, {"tcp", "udp"} }, + { 3544, {"teredo"}, {"tcp", "udp"} }, + { 3587, {"p2pgroup"}, {"tcp", "udp"} }, + { 3702, {"ws-discovery", "upnp-discovery"}, {"udp", "tcp"} }, + { 3776, {"dvcprov-port"}, {"tcp", "udp"} }, + { 3847, {"msfw-control"}, {"tcp"} }, + { 3882, {"msdts1"}, {"tcp"} }, + { 3935, {"sdp-portmapper"}, {"tcp", "udp"} }, + { 4350, {"net-device"}, {"tcp", "udp"} }, + { 4500, {"ipsec-msft"}, {"tcp", "udp"} }, + { 5355, {"llmnr"}, {"tcp", "udp"} }, + { 5357, {"wsd"}, {"tcp"} }, + { 5358, {"wsd"}, {"tcp"} }, + { 5678, {"rrac"}, {"tcp", "udp"} }, + { 5679, {"dccm"}, {"tcp", "udp"} }, + { 5720, {"ms-licensing"}, {"tcp", "udp"} }, + { 6073, {"directplay8"}, {"tcp", "udp"} }, + { 9535, {"man"}, {"tcp"} }, + { 9753, {"rasadv"}, {"tcp", "udp"} }, + { 11320, {"imip-channels"}, {"tcp", "udp"} }, + { 47624, {"directplaysrvr"}, {"tcp", "udp"} }, +}; + /*********************************************************************** * getservbyname (WS2_32.55) */ struct WS_servent* WINAPI WS_getservbyname(const char *name, const char *proto) { struct WS_servent* retval = NULL; - struct servent* serv; - char *name_str; - char *proto_str = NULL; - - if (!(name_str = strdup_lower(name))) return NULL; - - if (proto && *proto) + int i, j, k; + for (i = 0; i < ARRAY_SIZE(services); i++) { - if (!(proto_str = strdup_lower(proto))) + for (j = 0; services[i].names[j]; j++) { - HeapFree( GetProcessHeap(), 0, name_str ); - return NULL; + if (_strnicmp(services[i].names[j], name, -1) != 0) continue; + for (k = 0; k < ARRAY_SIZE(services[0].protos) && services[i].protos[k]; k++) + { + if (proto && _strnicmp(services[i].protos[k], proto, -1) != 0) continue; + retval = WS_create_se(services[i].names[0], (char **)services[i].names + 1, + services[i].port, services[i].protos[k]); + goto found; + } + break; } } + if (!retval) + { + WARN("service %s/%s not found\n", debugstr_a(name), debugstr_a(proto)); + SetLastError(WSANO_DATA); + } +found: + TRACE("%s/%s ret %p\n", debugstr_a(name), debugstr_a(proto), retval); + return retval; +}
- EnterCriticalSection( &csWSgetXXXbyYYY ); - serv = getservbyname(name_str, proto_str); - if( serv != NULL ) +/*********************************************************************** + * getservbyport (WS2_32.56) + */ +struct WS_servent* WINAPI WS_getservbyport(int port, const char *proto) +{ + struct WS_servent* retval = NULL; + int i, j; + port = ntohs(port); + for (i = 0; i < ARRAY_SIZE(services); i++) + { + if (services[i].port != port) continue; + for (j = 0; j < ARRAY_SIZE(services[0].protos) && services[i].protos[j]; j++) + { + if (proto && _strnicmp(services[i].protos[j], proto, -1) != 0) continue; + retval = WS_create_se(services[i].names[0], (char **)services[i].names + 1, + services[i].port, services[i].protos[j]); + goto found; + } + } + if (!retval) { - retval = WS_dup_se(serv); + WARN("service %d/%s not found\n", port, debugstr_a(proto)); + SetLastError(WSANO_DATA); } - else SetLastError(WSANO_DATA); - LeaveCriticalSection( &csWSgetXXXbyYYY ); - HeapFree( GetProcessHeap(), 0, proto_str ); - HeapFree( GetProcessHeap(), 0, name_str ); - TRACE( "%s, %s ret %p\n", debugstr_a(name), debugstr_a(proto), retval ); +found: + TRACE("%d/%s ret %p\n", port, debugstr_a(proto), retval); return retval; }
+ /*********************************************************************** * freeaddrinfo (WS2_32.@) */ @@ -7285,32 +7488,6 @@ int WINAPI GetNameInfoW(const SOCKADDR *sa, WS_socklen_t salen, PWCHAR host, return ret; }
-/*********************************************************************** - * getservbyport (WS2_32.56) - */ -struct WS_servent* WINAPI WS_getservbyport(int port, const char *proto) -{ - struct WS_servent* retval = NULL; -#ifdef HAVE_GETSERVBYPORT - struct servent* serv; - char *proto_str = NULL; - - if (proto && *proto) - { - if (!(proto_str = strdup_lower(proto))) return NULL; - } - EnterCriticalSection( &csWSgetXXXbyYYY ); - if( (serv = getservbyport(port, proto_str)) != NULL ) { - retval = WS_dup_se(serv); - } - else SetLastError(WSANO_DATA); - LeaveCriticalSection( &csWSgetXXXbyYYY ); - HeapFree( GetProcessHeap(), 0, proto_str ); -#endif - TRACE("%d (i.e. port %d), %s ret %p\n", port, (int)ntohl(port), debugstr_a(proto), retval); - return retval; -} -
/*********************************************************************** * gethostname (WS2_32.57) @@ -7795,12 +7972,7 @@ INT WINAPI WSAUnhookBlockingHook(void)
/* ----------------------------------- end of API stuff */
-/* ----------------------------------- helper functions - - * - * TODO: Merge WS_dup_..() stuff into one function that - * would operate with a generic structure containing internal - * pointers (via a template of some kind). - */ +/* ----------------------------------- helper functions */
static int list_size(char** l, int item_size) { @@ -7935,31 +8107,20 @@ static struct WS_protoent *WS_create_pe( const char *name, char **aliases, int p
/* ----- servent */
-static struct WS_servent *WS_dup_se(const struct servent* p_se) +static struct WS_servent *WS_create_se( const char *name, char **aliases, int port, const char *proto ) { - char *p; - struct WS_servent *p_to; - - int size = (sizeof(*p_se) + - strlen(p_se->s_proto) + 1 + - strlen(p_se->s_name) + 1 + - list_size(p_se->s_aliases, 0)); - - if (!(p_to = check_buffer_se(size))) return NULL; - p_to->s_port = p_se->s_port; - - p = (char *)(p_to + 1); - p_to->s_name = p; - strcpy(p, p_se->s_name); - p += strlen(p) + 1; - - p_to->s_proto = p; - strcpy(p, p_se->s_proto); - p += strlen(p) + 1; + struct WS_servent *ret; + unsigned int size = sizeof(*ret) + strlen(name) + 1 + strlen(proto) + sizeof(char *) + list_size(aliases, 0);
- p_to->s_aliases = (char **)p; - list_dup(p_se->s_aliases, p_to->s_aliases, 0); - return p_to; + if (!(ret = check_buffer_se( size ))) return NULL; + ret->s_port = htons(port); + ret->s_name = (char *)(ret + 1); + ret->s_proto = (char *)ret->s_name + strlen(name) + 1; + strcpy( ret->s_name, name ); + strcpy( ret->s_proto, proto ); + ret->s_aliases = (char **)ret->s_proto + strlen(proto) / sizeof(char *) + 1; + list_dup( aliases, ret->s_aliases, 0 ); + return ret; }
diff --git a/dlls/ws2_32/tests/protocol.c b/dlls/ws2_32/tests/protocol.c index d6e454a5fb..b230ac80c8 100644 --- a/dlls/ws2_32/tests/protocol.c +++ b/dlls/ws2_32/tests/protocol.c @@ -39,6 +39,13 @@ | XP1_SUPPORT_MULTIPOINT \ | XP1_IFS_HANDLES)
+#define PRIVATE_PORT_START 49152 + +#define TEST_TIMEOUT 30 /* Seconds to wait before killing child threads + after server initialization, if something hangs */ +#define NUM_THREADS 3 /* Number of threads to run getservbyname */ +#define NUM_QUERIES 250 /* Number of getservbyname queries per thread */ + static void test_service_flags(int family, int version, int socktype, int protocol, DWORD testflags) { DWORD expectedflags = 0; @@ -290,6 +297,356 @@ static void test_getprotobynumber(void) } }
+struct service +{ + unsigned short port; + const char *names[2]; + const char *protos[2]; + enum { MISSING = 0x1, RENAMED = 0x2 } flags; +}; + +static const struct service services[] = +{ + { 7, {"echo"}, {"tcp", "udp"} }, + { 9, {"discard", "sink"}, {"tcp", "udp"} }, + { 11, {"systat", "users"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 13, {"daytime"}, {"tcp", "udp"} }, + { 17, {"qotd", "quote"}, {"tcp", "udp"} }, + { 19, {"chargen", "ttytst"}, {"tcp", "udp"} }, + { 20, {"ftp-data"}, {"tcp"} }, + { 21, {"ftp"}, {"tcp"} }, + { 22, {"ssh"}, {"tcp"}, MISSING /* xp */ }, + { 23, {"telnet"}, {"tcp"} }, + { 25, {"smtp", "mail"}, {"tcp"} }, + { 37, {"time", "timserver"}, {"tcp", "udp"} }, + { 39, {"rlp", "resource"}, {"udp"} }, + { 42, {"nameserver", "name"}, {"tcp", "udp"} }, + { 43, {"nicname", "whois"}, {"tcp"} }, + { 53, {"domain"}, {"tcp", "udp"} }, + { 67, {"bootps", "dhcps"}, {"udp"} }, + { 68, {"bootpc", "dhcpc"}, {"udp"} }, + { 69, {"tftp"}, {"udp"} }, + { 70, {"gopher"}, {"tcp"} }, + { 79, {"finger"}, {"tcp"} }, + { 80, {"http", "www"}, {"tcp"} }, + { 81, {"hosts2-ns"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 88, {"kerberos", "krb5"}, {"tcp", "udp"} }, + { 101, {"hostname", "hostnames"}, {"tcp"} }, + { 102, {"iso-tsap"}, {"tcp"} }, + { 107, {"rtelnet"}, {"tcp"} }, + { 109, {"pop2", "postoffice"}, {"tcp"} }, + { 110, {"pop3"}, {"tcp"} }, + { 111, {"sunrpc", "rpcbind"}, {"tcp", "udp"} }, + { 113, {"auth", "ident"}, {"tcp"} }, + { 117, {"uucp-path"}, {"tcp"} }, + { 118, {"sqlserv"}, {"tcp"}, MISSING /* xp */ }, + { 119, {"nntp", "usenet"}, {"tcp"} }, + { 123, {"ntp"}, {"udp"} }, + { 135, {"epmap", "loc-srv"}, {"tcp", "udp"} }, + { 137, {"netbios-ns", "nbname"}, {"tcp", "udp"} }, + { 138, {"netbios-dgm", "nbdatagram"}, {"udp"} }, + { 139, {"netbios-ssn", "nbsession"}, {"tcp"} }, + { 143, {"imap", "imap4"}, {"tcp"} }, + { 150, {"sql-net"}, {"tcp"}, MISSING /* xp */ }, + { 156, {"sqlsrv"}, {"tcp"}, MISSING /* xp */ }, + { 158, {"pcmail-srv"}, {"tcp"} }, + { 161, {"snmp"}, {"udp"} }, + { 162, {"snmptrap", "snmp-trap"}, {"udp"} }, + { 170, {"print-srv"}, {"tcp"} }, + { 179, {"bgp"}, {"tcp"} }, + { 194, {"irc"}, {"tcp"} }, + { 213, {"ipx"}, {"udp"} }, + { 322, {"rtsps"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 349, {"mftp"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 389, {"ldap"}, {"tcp"} }, + { 443, {"https", "MCom"}, {"tcp", "udp"} }, + { 445, {"microsoft-ds"}, {"tcp", "udp"} }, + { 464, {"kpasswd"}, {"tcp", "udp"} }, + { 500, {"isakmp", "ike"}, {"udp"} }, + { 507, {"crs"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 512, {"exec"}, {"tcp"} }, + { 512, {"biff", "comsat"}, {"udp", "tcp"}, MISSING /* win10 */ }, + { 513, {"login"}, {"tcp"} }, + { 513, {"who", "whod"}, {"udp", "tcp"}, MISSING /* win10 */ }, + { 514, {"cmd", "shell"}, {"tcp"} }, + { 514, {"syslog"}, {"udp", "tcp"}, MISSING /* win10 */ }, + { 515, {"printer", "spooler"}, {"tcp"} }, + { 517, {"talk"}, {"udp"} }, + { 518, {"ntalk"}, {"udp"} }, + { 520, {"efs"}, {"tcp"} }, + { 520, {"router", "route"}, {"udp", "tcp"}, MISSING /* win10 */ }, + { 522, {"ulp"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 525, {"timed", "timeserver"}, {"udp"} }, + { 526, {"tempo", "newdate"}, {"tcp"} }, + { 529, {"irc-serv"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 530, {"courier", "rpc"}, {"tcp"} }, + { 531, {"conference", "chat"}, {"tcp"} }, + { 532, {"netnews", "readnews"}, {"tcp"} }, + { 533, {"netwall"}, {"udp"} }, + { 540, {"uucp", "uucpd"}, {"tcp"} }, + { 543, {"klogin"}, {"tcp"} }, + { 544, {"kshell", "krcmd"}, {"tcp"} }, + { 546, {"dhcpv6-client"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 547, {"dhcpv6-server"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 548, {"afpovertcp"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 550, {"new-rwho", "new-who"}, {"udp"} }, + { 554, {"rtsp"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 556, {"remotefs", "rfs"}, {"tcp"} }, + { 560, {"rmonitor", "rmonitord"}, {"udp"} }, + { 561, {"monitor"}, {"udp"} }, + { 563, {"nntps", "snntp"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 565, {"whoami"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 568, {"ms-shuttle"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 569, {"ms-rome"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 593, {"http-rpc-epmap"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 612, {"hmmp-ind"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 613, {"hmmp-op"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 636, {"ldaps", "sldap"}, {"tcp"} }, + { 666, {"doom"}, {"tcp", "udp"} }, + { 691, {"msexch-routing"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 749, {"kerberos-adm"}, {"tcp", "udp"} }, + { 750, {"kerberos-iv"}, {"udp"} }, + { 800, {"mdbs_daemon"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 989, {"ftps-data"}, {"tcp"}, MISSING /* xp */ }, + { 990, {"ftps"}, {"tcp"}, MISSING /* xp */ }, + { 992, {"telnets"}, {"tcp"}, MISSING /* xp */ }, + { 993, {"imaps"}, {"tcp"}, MISSING /* xp */ }, + { 994, {"ircs"}, {"tcp"}, MISSING /* xp */ }, + { 995, {"pop3s", "spop3"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 1034, {"activesync"}, {"tcp"}, MISSING /* xp */ }, + { 1109, {"kpop"}, {"tcp"} }, + { 1110, {"nfsd-status"}, {"tcp"}, MISSING /* xp */ }, + { 1110, {"nfsd-keepalive"}, {"udp"}, MISSING /* xp */ }, + { 1155, {"nfa"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 1167, {"phone"}, {"udp"} }, + { 1270, {"opsmgr"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 1433, {"ms-sql-s"}, {"tcp", "udp"} }, + { 1434, {"ms-sql-m"}, {"tcp", "udp"} }, + { 1477, {"ms-sna-server"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 1478, {"ms-sna-base"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 1512, {"wins"}, {"tcp", "udp"} }, + { 1524, {"ingreslock", "ingres"}, {"tcp"} }, + { 1607, {"stt"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 1701, {"l2tp"}, {"udp"} }, + { 1711, {"pptconference"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 1723, {"pptp"}, {"tcp"} }, + { 1731, {"msiccp"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 1745, {"remote-winsock"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 1755, {"ms-streaming"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 1801, {"msmq"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 1812, {"radius"}, {"udp"} }, + { 1813, {"radacct"}, {"udp"} }, + { 1863, {"msnp"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 1900, {"ssdp"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 1944, {"close-combat"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2049, {"nfsd", "nfs"}, {"udp"} }, + { 2053, {"knetd"}, {"tcp"} }, + { 2106, {"mzap"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2177, {"qwave"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2234, {"directplay"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2382, {"ms-olap3"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2383, {"ms-olap4"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2393, {"ms-olap1"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2394, {"ms-olap2"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2460, {"ms-theater"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2504, {"wlbs"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2525, {"ms-v-worlds"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2701, {"sms-rcinfo"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2702, {"sms-xfer"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2703, {"sms-chat"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2704, {"sms-remctrl"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2725, {"msolap-ptp2"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 2869, {"icslap"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 3020, {"cifs"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 3074, {"xbox"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 3126, {"ms-dotnetster"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 3132, {"ms-rule-engine"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 3268, {"msft-gc"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 3269, {"msft-gc-ssl"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 3343, {"ms-cluster-net"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 3389, {"ms-wbt-server"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 3535, {"ms-la"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 3540, {"pnrp-port"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 3544, {"teredo"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 3587, {"p2pgroup"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 3702, {"ws-discovery", "upnp-discovery"}, {"udp", "tcp"}, MISSING /* xp */ | RENAMED /* 2008 */ }, + { 3776, {"dvcprov-port"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 3847, {"msfw-control"}, {"tcp"}, MISSING /* xp */ }, + { 3882, {"msdts1"}, {"tcp"}, MISSING /* xp */ }, + { 3935, {"sdp-portmapper"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 4350, {"net-device"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 4500, {"ipsec-msft"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 5355, {"llmnr"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 5357, {"wsd"}, {"tcp"}, MISSING /* xp */ }, + { 5358, {"wsd"}, {"tcp"}, MISSING /* xp */ }, + { 5678, {"rrac"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 5679, {"dccm"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 5720, {"ms-licensing"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 6073, {"directplay8"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 9535, {"man"}, {"tcp"} }, + { 9753, {"rasadv"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 11320, {"imip-channels"}, {"tcp", "udp"}, MISSING /* xp */ }, + { 47624, {"directplaysrvr"}, {"tcp", "udp"}, MISSING /* xp */ }, +}; + +static const struct service *find_service(int port, const char *proto) +{ + int i, j; + for (i = 0; i < ARRAY_SIZE(services) && services[i].port <= port; i++) + { + if (services[i].port != port) continue; + for (j = 0; j < ARRAY_SIZE(services[0].protos) && services[i].protos[j]; j++) + { + if (!proto || _stricmp(proto, services[i].protos[j]) == 0) + return &services[i]; + } + } + return NULL; +} + +static DWORD WINAPI do_getservbyname(void *param) +{ + HANDLE *starttest = param; + int i, j, k, l; + struct servent *results[ARRAY_SIZE(services)]; + char all_caps_name[16]; + + if (starttest) + { + ok(WaitForSingleObject(*starttest, TEST_TIMEOUT * 1000) != WAIT_TIMEOUT, + "test_getservbyname: timeout waiting for start signal\n"); + } + + /* ensure that necessary buffer resizes are completed */ + for (i = 0; i < 2; i++) + results[i] = getservbyname(services[i].names[0], NULL); + + for (i = 0; i < (starttest ? NUM_QUERIES / 2 : 1); i++) + { + for (j = 0; j < (starttest ? 2 : ARRAY_SIZE(services)); j++) + { + if (j > 0 && strcmp(services[j].names[0], services[j-1].names[0]) == 0) continue; + for (k = 0; k < ARRAY_SIZE(services[0].names) && services[j].names[k]; k++) + { + for (l = 0; services[j].names[k][l]; l++) + all_caps_name[l] = toupper(services[j].names[k][l]); + all_caps_name[l] = 0; + for (l = 0; l < ARRAY_SIZE(services[0].protos); l++) + { + results[j] = getservbyname(services[j].names[k], services[j].protos[l]); + ok(results[j] != NULL || broken(services[j].flags & MISSING), + "getservbyname could not retrieve information for %s/%s: %d\n", + services[j].names[k], wine_dbgstr_a(services[j].protos[l]), WSAGetLastError()); + if (!results[j]) continue; + ok(ntohs(results[j]->s_port) == services[j].port, + "getservbyname returned the wrong port for %s/%s: %d\n", + services[j].names[k], wine_dbgstr_a(services[j].protos[l]), ntohs(results[j]->s_port)); + ok(!strcmp(results[j]->s_proto, services[j].protos[l] ? services[j].protos[l] : services[j].protos[0]), + "getservbyname returned the wrong protocol for %s/%s: %s\n", + services[j].names[k], wine_dbgstr_a(services[j].protos[l]), results[j]->s_proto); + ok(!strcmp(results[j]->s_name, services[j].names[0]) || + broken((services[j].flags & RENAMED) && !strcmp(results[j]->s_name, services[j].names[1])), + "getservbyname returned the wrong name for %s/%s: %s\n", + services[j].names[k], wine_dbgstr_a(services[j].protos[l]), results[j]->s_name); + + results[j] = getservbyname(all_caps_name, services[j].protos[l]); + ok(ntohs(results[j]->s_port) == services[j].port, + "getservbyname returned the wrong port for %s/%s: %d\n", + all_caps_name, wine_dbgstr_a(services[j].protos[l]), ntohs(results[j]->s_port)); + ok(!strcmp(results[j]->s_proto, services[j].protos[l] ? services[j].protos[l] : services[j].protos[0]), + "getservbyname returned the wrong protocol for %s/%s: %s\n", + all_caps_name, wine_dbgstr_a(services[j].protos[l]), results[j]->s_proto); + ok(!strcmp(results[j]->s_name, services[j].names[0]) || + broken((services[j].flags & RENAMED) && !strcmp(results[j]->s_name, services[j].names[1])), + "getservbyname returned the wrong name for %s/%s: %s\n", + all_caps_name, wine_dbgstr_a(services[j].protos[l]), results[j]->s_name); + } + } + } + ok(results[0] == results[1], + "getservbyname: winsock resized servent buffer when not necessary\n"); + } + + return 0; +} + +static void test_getservbyname(void) +{ + int i; + HANDLE starttest, thread[NUM_THREADS]; + DWORD thread_id[NUM_THREADS]; + + /* test the complete list of service entries */ + do_getservbyname(NULL); + + /* test thread safety using just the first two service entries */ + starttest = CreateEventA(NULL, 1, 0, "test_getservbyname_starttest"); + + /* create threads */ + for (i = 0; i < NUM_THREADS; i++) + thread[i] = CreateThread(NULL, 0, do_getservbyname, &starttest, 0, &thread_id[i]); + + /* signal threads to start */ + SetEvent(starttest); + + for (i = 0; i < NUM_THREADS; i++) + WaitForSingleObject(thread[i], TEST_TIMEOUT * 1000); +} + +static void test_getservbyport(void) +{ + static const char *test_protos[] = { NULL, "tcp", "udp", "icmp", "Tcp", "udP" }; + struct servent *ent; + const struct service *ref; + int i, j; + + /* Testing all port/protocol combinations takes a very long time on Windows. To avoid timeouts, + * don't test the private port range and skip the tests for specific protocols if there is no + * defined service on a particular port for any protocol. */ + for (i = 0; i <= PRIVATE_PORT_START; i++) + { + for (j = 0; j < ARRAY_SIZE(test_protos); j++) + { + ent = getservbyport(htons(i), test_protos[j]); + ref = find_service(i, test_protos[j]); + + if (!ref) + { + ok(!ent, "Expected service %d/%s to be undefined, got %s\n", + i, wine_dbgstr_a(test_protos[j]), wine_dbgstr_a(ent ? ent->s_name : NULL)); + if (!ent && j == 0) break; + continue; + } + + ok((ent && ent->s_name && strcmp(ent->s_name, ref->names[0]) == 0) || + broken((ref->flags & MISSING) && !ent) || + broken((ref->flags & RENAMED) && ent && ent->s_name && strcmp(ent->s_name, ref->names[1]) == 0), + "Expected service %d/%s to be %s, got %s\n", + i, wine_dbgstr_a(test_protos[j]), wine_dbgstr_a(ref->names[0]), + wine_dbgstr_a(ent ? ent->s_name : NULL)); + + if (ref->names[1]) + { + ok((ent && ent->s_aliases && ent->s_aliases[0] && + strcmp(ent->s_aliases[0], ref->names[1]) == 0) || + broken((ref->flags & MISSING) && !ent) || + broken((ref->flags & RENAMED) && ent && ent->s_aliases && !ent->s_aliases[0]), + "Expected service %d/%s alias 0 to be %s, got %s\n", + i, wine_dbgstr_a(test_protos[j]), wine_dbgstr_a(ref->names[1]), + wine_dbgstr_a(ent && ent->s_aliases ? ent->s_aliases[0] : NULL)); + } + else + { + ok((ent && ent->s_aliases && !ent->s_aliases[0]) || + broken((ref->flags & MISSING) && !ent), + "Expected service %d/%s alias 0 to be undefined, got %s\n", + i, wine_dbgstr_a(test_protos[j]), + wine_dbgstr_a(ent && ent->s_aliases ? ent->s_aliases[0] : NULL)); + } + } + } +} + START_TEST( protocol ) { WSADATA data; @@ -301,4 +658,6 @@ START_TEST( protocol ) test_WSAEnumProtocolsW(); test_getprotobyname(); test_getprotobynumber(); + test_getservbyname(); + test_getservbyport(); } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index b7a3fc4453..511fbf5f1d 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -45,9 +45,6 @@
#define NUM_UDP_PEERS 3 /* Number of UDP sockets to create and test > 1 */
-#define NUM_THREADS 3 /* Number of threads to run getservbyname */ -#define NUM_QUERIES 250 /* Number of getservbyname queries per thread */ - #define SERVERIP "127.0.0.1" /* IP to bind to */ #define SERVERPORT 9374 /* Port number to bind to */
@@ -2401,68 +2398,6 @@ static void test_UDP(void) } }
-static DWORD WINAPI do_getservbyname( void *param ) -{ - struct { - const char *name; - const char *proto; - int port; - } serv[2] = { {"domain", "udp", 53}, {"telnet", "tcp", 23} }; - - HANDLE *starttest = param; - int i, j; - struct servent *pserv[2]; - - ok ( WaitForSingleObject ( *starttest, TEST_TIMEOUT * 1000 ) != WAIT_TIMEOUT, - "test_getservbyname: timeout waiting for start signal\n" ); - - /* ensure that necessary buffer resizes are completed */ - for ( j = 0; j < 2; j++) { - pserv[j] = getservbyname ( serv[j].name, serv[j].proto ); - } - - for ( i = 0; i < NUM_QUERIES / 2; i++ ) { - for ( j = 0; j < 2; j++ ) { - pserv[j] = getservbyname ( serv[j].name, serv[j].proto ); - ok ( pserv[j] != NULL || broken(pserv[j] == NULL) /* win8, fixed in win81 */, - "getservbyname could not retrieve information for %s: %d\n", serv[j].name, WSAGetLastError() ); - if ( !pserv[j] ) continue; - ok ( pserv[j]->s_port == htons(serv[j].port), - "getservbyname returned the wrong port for %s: %d\n", serv[j].name, ntohs(pserv[j]->s_port) ); - ok ( !strcmp ( pserv[j]->s_proto, serv[j].proto ), - "getservbyname returned the wrong protocol for %s: %s\n", serv[j].name, pserv[j]->s_proto ); - ok ( !strcmp ( pserv[j]->s_name, serv[j].name ), - "getservbyname returned the wrong name for %s: %s\n", serv[j].name, pserv[j]->s_name ); - } - - ok ( pserv[0] == pserv[1] || broken(pserv[0] != pserv[1]) /* win8, fixed in win81 */, - "getservbyname: winsock resized servent buffer when not necessary\n" ); - } - - return 0; -} - -static void test_getservbyname(void) -{ - int i; - HANDLE starttest, thread[NUM_THREADS]; - DWORD thread_id[NUM_THREADS]; - - starttest = CreateEventA ( NULL, 1, 0, "test_getservbyname_starttest" ); - - /* create threads */ - for ( i = 0; i < NUM_THREADS; i++ ) { - thread[i] = CreateThread ( NULL, 0, do_getservbyname, &starttest, 0, &thread_id[i] ); - } - - /* signal threads to start */ - SetEvent ( starttest ); - - for ( i = 0; i < NUM_THREADS; i++) { - WaitForSingleObject ( thread[i], TEST_TIMEOUT * 1000 ); - } -} - static void test_WSASocket(void) { SOCKET sock = INVALID_SOCKET; @@ -11374,7 +11309,6 @@ START_TEST( sock )
test_UDP();
- test_getservbyname(); test_WSASocket(); test_WSADuplicateSocket(); test_WSAEnumNetworkEvents();