void sk_init(void); /* called once at program startup */
SockAddr sk_namelookup(char *host, char **canonicalname);
+void sk_getaddr(SockAddr addr, char *buf, int buflen);
void sk_addr_free(SockAddr addr);
Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
{
int events;
if (startup) {
- events = FD_READ | FD_WRITE | FD_OOB | FD_CLOSE | FD_ACCEPT;
+ events = (FD_CONNECT | FD_READ | FD_WRITE |
+ FD_OOB | FD_CLOSE | FD_ACCEPT);
} else {
events = 0;
}
if (!WSAEnumNetworkEvents(socket, NULL, &things)) {
noise_ultralight(socket);
noise_ultralight(things.lNetworkEvents);
+ if (things.lNetworkEvents & FD_CONNECT)
+ connopen &= select_result(wp, (LPARAM) FD_CONNECT);
if (things.lNetworkEvents & FD_READ)
connopen &= select_result(wp, (LPARAM) FD_READ);
if (things.lNetworkEvents & FD_CLOSE)
return 1;
}
+static void raw_sent(Plug plug, int bufsize)
+{
+ raw_bufsize = bufsize;
+}
+
/*
* Called to set up the raw connection.
*
{
static struct plug_function_table fn_table = {
raw_closing,
- raw_receive
+ raw_receive,
+ raw_sent
}, *fn_table_ptr = &fn_table;
SockAddr addr;
/*
* Try to find host.
*/
+ {
+ char buf[200];
+ sprintf(buf, "Looking up host \"%.170s\"", host);
+ logevent(buf);
+ }
addr = sk_namelookup(host, realhost);
if ((err = sk_addr_error(addr)))
return err;
/*
* Open socket.
*/
+ {
+ char buf[200], addrbuf[100];
+ sk_getaddr(addr, addrbuf, 100);
+ sprintf(buf, "Connecting to %.100s port %d", addrbuf, port);
+ logevent(buf);
+ }
s = sk_new(addr, port, 0, 1, &fn_table_ptr);
if ((err = sk_socket_error(s)))
return err;
return 1;
}
+static void rlogin_sent(Plug plug, int bufsize)
+{
+ rlogin_bufsize = bufsize;
+}
+
/*
* Called to set up the rlogin connection.
*
{
static struct plug_function_table fn_table = {
rlogin_closing,
- rlogin_receive
+ rlogin_receive,
+ rlogin_sent
}, *fn_table_ptr = &fn_table;
SockAddr addr;
/*
* Try to find host.
*/
+ {
+ char buf[200];
+ sprintf(buf, "Looking up host \"%.170s\"", host);
+ logevent(buf);
+ }
addr = sk_namelookup(host, realhost);
if ((err = sk_addr_error(addr)))
return err;
/*
* Open socket.
*/
+ {
+ char buf[200], addrbuf[100];
+ sk_getaddr(addr, addrbuf, 100);
+ sprintf(buf, "Connecting to %.100s port %d", addrbuf, port);
+ logevent(buf);
+ }
s = sk_new(addr, port, 1, 0, &fn_table_ptr);
if ((err = sk_socket_error(s)))
return err;
/*
* Try to find host.
*/
+ {
+ char buf[200];
+ sprintf(buf, "Looking up host \"%.170s\"", host);
+ logevent(buf);
+ }
addr = sk_namelookup(host, realhost);
if ((err = sk_addr_error(addr)))
return err;
/*
* Open socket.
*/
+ {
+ char buf[200], addrbuf[100];
+ sk_getaddr(addr, addrbuf, 100);
+ sprintf(buf, "Connecting to %.100s port %d", addrbuf, port);
+ logevent(buf);
+ }
s = sk_new(addr, port, 0, 1, &fn_table_ptr);
if ((err = sk_socket_error(s)))
return err;
return 1;
}
+static void telnet_sent(Plug plug, int bufsize)
+{
+ telnet_bufsize = bufsize;
+}
+
/*
* Called to set up the Telnet connection.
*
{
static struct plug_function_table fn_table = {
telnet_closing,
- telnet_receive
+ telnet_receive,
+ telnet_sent
}, *fn_table_ptr = &fn_table;
SockAddr addr;
/*
* Try to find host.
*/
+ {
+ char buf[200];
+ sprintf(buf, "Looking up host \"%.170s\"", host);
+ logevent(buf);
+ }
addr = sk_namelookup(host, realhost);
if ((err = sk_addr_error(addr)))
return err;
/*
* Open socket.
*/
+ {
+ char buf[200], addrbuf[100];
+ sk_getaddr(addr, addrbuf, 100);
+ sprintf(buf, "Connecting to %.100s port %d", addrbuf, port);
+ logevent(buf);
+ }
s = sk_new(addr, port, 0, 1, &fn_table_ptr);
if ((err = sk_socket_error(s)))
return err;
int msg, events;
if (startup) {
msg = WM_NETEVENT;
- events = FD_READ | FD_WRITE | FD_OOB | FD_CLOSE | FD_ACCEPT;
+ events = (FD_CONNECT | FD_READ | FD_WRITE |
+ FD_OOB | FD_CLOSE | FD_ACCEPT);
} else {
msg = events = 0;
}
pending_netevent = TRUE;
pend_netevent_wParam = wParam;
pend_netevent_lParam = lParam;
+ if (WSAGETSELECTEVENT(lParam) != FD_READ)
+ enact_pending_netevent();
+
time(&last_movement);
return 0;
case WM_SETFOCUS:
Plug plug;
void *private_ptr;
bufchain output_data;
+ int connected;
int writable;
int frozen; /* this causes readability notifications to be ignored */
int frozen_readable; /* this means we missed at least one readability
return ret;
}
+void sk_getaddr(SockAddr addr, char *buf, int buflen)
+{
+#ifdef IPV6
+ if (addr->family == AF_INET) {
+#endif
+ struct in_addr a;
+ a.s_addr = htonl(addr->address);
+ strncpy(buf, inet_ntoa(a), buflen);
+#ifdef IPV6
+ } else {
+ FIXME; /* I don't know how to get a text form of an IPv6 address. */
+ }
+#endif
+}
+
void sk_addr_free(SockAddr addr)
{
sfree(addr);
ret->error = NULL;
ret->plug = plug;
bufchain_init(&ret->output_data);
- ret->writable = 1; /* to start with */
+ ret->connected = 0; /* to start with */
+ ret->writable = 0; /* to start with */
ret->sending_oob = 0;
ret->frozen = 0;
ret->frozen_readable = 0;
a.sin_addr.s_addr = htonl(addr->address);
a.sin_port = htons((short) port);
}
+
+ /* Set up a select mechanism. This could be an AsyncSelect on a
+ * window, or an EventSelect on an event object. */
+ errstr = do_select(s, 1);
+ if (errstr) {
+ ret->error = errstr;
+ return (Socket) ret;
+ }
+
if ((
#ifdef IPV6
connect(s, ((addr->family == AF_INET6) ?
#endif
) == SOCKET_ERROR) {
err = WSAGetLastError();
- ret->error = winsock_error_string(err);
- return (Socket) ret;
- }
-
- /* Set up a select mechanism. This could be an AsyncSelect on a
- * window, or an EventSelect on an event object. */
- errstr = do_select(s, 1);
- if (errstr) {
- ret->error = errstr;
- return (Socket) ret;
+ /*
+ * We expect a potential EWOULDBLOCK here, because the
+ * chances are the front end has done a select for
+ * FD_CONNECT, so that connect() will complete
+ * asynchronously.
+ */
+ if ( err != WSAEWOULDBLOCK ) {
+ ret->error = winsock_error_string(err);
+ return (Socket) ret;
+ }
+ } else {
+ /*
+ * If we _don't_ get EWOULDBLOCK, the connect has completed
+ * and we should set the socket as writable.
+ */
+ ret->writable = 1;
}
add234(sktree, ret);
noise_ultralight(lParam);
switch (WSAGETSELECTEVENT(lParam)) {
+ case FD_CONNECT:
+ s->connected = s->writable = 1;
+ break;
case FD_READ:
/* In the case the socket is still frozen, we don't even bother */
if (s->frozen) {