Skip to content

Loading…

Added windows IPv6 support #303

Closed
wants to merge 13 commits into from

5 participants

@stakach

Also increased file and socket limits

@stakach

@tmm1 just thought I'd let you know that I've completely solved the issues with connection weirdness and eventmachine on windows.

The FD_SETSIZE must be the same on ruby installer as it is in eventmachine.
The next release of ruby installer will increase the limit to 32767 so this must be reflected in project.h
Previous versions of ruby installer ruby will continue to work as they used to.

Thanks for your on going help in the matter. Very much appreciated and helpful.
I'll also stop harassing you now too. ;)

@stakach stakach referenced this pull request in oneclick/rubyinstaller
Closed

Low socket limit #104

@stakach

The ruby installer issue oneclick/rubyinstaller#104

@stakach

@tmm1 the final product rolled out at Sydney University running on eventmachine and rubyinstaller ruby.
I did a little write up on the project.

https://groups.google.com/forum/?fromgroups#!topic/rubyinstaller/0UlbSlwXa6U

@stakach stakach referenced this pull request in rubinius/rubinius
Closed

Eventmachine Support on Windows #1600

@rdp
rdp commented

why does it have to match the rubyinstaller FD_SETSIZE again?

@stakach

From observations on Windows 2008 R2 x64 VM
1. Ruby SETSIZE < EM SETSIZE

  • Ruby SETSIZE is enforced
  • Unpredictable behaviour beyond Ruby SETSIZE (at one point I had sockets surviving program termination that remained ESTABLISHED)
    1. Ruby SETSIZE > EM SETSIZE
  • segfault
@rdp

actually ruby's extconf system will automagically set this to the higher number for you already, won't it? (i.e. you don't have to set it at all?)

Maybe.
I assume you would have to set it here too as it is compiled independently from ruby then loaded dynamically at run time.

I believe when ruby calls gcc it passes in the "original parameters ruby itself was built with" which includes the -DFD_SETSIZE config.

Sweet!
Ill do a test compile this afternoon and update the pull request.

Wait, we should leave it here as other projects such as http://rubini.us/ will not be including the flag.
See rubinius/rubinius#1600

If other projects don't include it then it should fall back to the default shouldn't it? (otherwise you'll see the descrepancies you noted)?

True that. I'll remove now and update the rubinius issue

@alor

have you tested it with rubyinstaller 1.9.3-p194 ?
i'm having some problems with it... see #319.

@Azolo

@stakach Since 8840d22 solves #319 and could be considered a fix this is beyond the scope of just this PR think you could extract it into a new one?

@stakach

Well the aim of this pull request was to improve windows support on eventmachine.

@tmm1 is there any reason we can't merge these changes and create a new windows release?

@stakach

@raggi maybe you could help?

@sodabrew

Note to self: Check if #570 includes this work.

@sodabrew sodabrew added this to the v1.2.0 milestone
@sodabrew

Superseded by #630

@sodabrew sodabrew closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Showing with 63 additions and 11 deletions.
  1. +53 −8 ext/em.cpp
  2. +9 −2 ext/project.h
  3. +1 −1 lib/em/version.rb
View
61 ext/em.cpp
@@ -97,7 +97,10 @@ EventMachine_t::EventMachine_t (EMCallback event_callback):
*/
#ifdef OS_WIN32
WSADATA w;
- WSAStartup (MAKEWORD (1, 1), &w);
+ int iResult = WSAStartup (MAKEWORD (1, 1), &w);
+ if(iResult != NO_ERROR)
+ throw std::runtime_error ("WSAStartup function failed");
+ _setmaxstdio(2048);
#endif
_InitializeLoopBreaker();
@@ -130,6 +133,10 @@ EventMachine_t::~EventMachine_t()
close (epfd);
if (kqfd != -1)
close (kqfd);
+
+ #ifdef OS_WIN32
+ WSACleanup(); // Clean up the windows network library
+ #endif
}
@@ -1470,14 +1477,50 @@ struct sockaddr *name2address (const char *server, int port, int *family, int *b
#endif
#ifdef OS_WIN32
- // TODO, must complete this branch. Windows doesn't have inet_pton.
- // A possible approach is to make a getaddrinfo call with the supplied
- // server address, constraining the hints to ipv6 and seeing if we
- // get any addresses.
- // For the time being, Ipv6 addresses aren't supported on Windows.
- #endif
+ // Windows doesn't have inet_pton.
+ // Make a getaddrinfo call with the supplied server address (hostname or ipv6 address),
+ // We pick the first valid result.
+ struct addrinfo *result = NULL;
+ struct addrinfo *ptr = NULL;
+ //struct addrinfo hints;
+
+ //memset (&hints, 0, sizeof(hints));
+ //hints.ai_family = AF_UNSPEC; // Hints not needed
+
+ if(getaddrinfo((char*)server, NULL, NULL, &result) == 0) {
+ for(ptr=result; ptr != NULL; ptr=ptr->ai_next) {
+ switch(ptr->ai_family) {
+
+ case AF_INET6:
+ memcpy((void*) &in6, (const void*)(ptr->ai_addr), sizeof(in6)); // Copy result
+ freeaddrinfo(result); // Prevent memory leaks
+
+ if (family)
+ *family = AF_INET6;
+ if (bind_size)
+ *bind_size = sizeof(in6);
+
+ in6.sin6_family = AF_INET6;
+ in6.sin6_port = htons (port);
+ return (struct sockaddr*)&in6;
+ case AF_INET:
+ memcpy((void*) &in4, (const void*)(ptr->ai_addr), sizeof(in4)); // Copy result
+ freeaddrinfo(result); // Prevent memory leaks
+
+ if (family)
+ *family = AF_INET;
+ if (bind_size)
+ *bind_size = sizeof(in4);
+
+ in4.sin_family = AF_INET;
+ in4.sin_port = htons (port);
+ return (struct sockaddr*)&in4;
+ }
+ }
+ }
+ #else
- hp = gethostbyname ((char*)server); // Windows requires the cast.
+ hp = gethostbyname ((char*)server); // Windows requires the cast, although no longer executed on windows
if (hp) {
in4.sin_addr.s_addr = ((in_addr*)(hp->h_addr))->s_addr;
if (family)
@@ -1489,6 +1532,8 @@ struct sockaddr *name2address (const char *server, int port, int *family, int *b
return (struct sockaddr*)&in4;
}
+ #endif
+
return NULL;
}
View
11 ext/project.h
@@ -81,16 +81,23 @@ typedef int SOCKET;
#endif /* OS_UNIX */
#ifdef OS_WIN32
-// 21Sep09: windows limits select() to 64 sockets by default, we increase it to 1024 here (before including winsock2.h)
-#define FD_SETSIZE 1024
+// 21Sep09: windows limits select() to 64 sockets by default, we increase here (before including winsock2.h)
+// 27March12: FD_SETSIZE is set at the ruby level and included automatically by extconf
+// #define FD_SETSIZE 32767
#define WIN32_LEAN_AND_MEAN
+// Add support for IPv6
+#define _WIN32_WINNT 0x501
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <rpc.h>
#include <fcntl.h>
#include <assert.h>
+#include <stdio.h>
+
+// link with Ws2_32.lib
+#pragma comment (lib, "Ws2_32.lib")
typedef int socklen_t;
typedef int pid_t;
View
2 lib/em/version.rb
@@ -1,3 +1,3 @@
module EventMachine
- VERSION = "1.0.0.beta.4"
+ VERSION = "1.0.0.beta.5"
end
Something went wrong with that request. Please try again.