From: owen Date: Tue, 22 Feb 2005 23:40:47 +0000 (+0000) Subject: A first attempt at listening sockets in Open Transport. X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/commitdiff_plain/a53784ab02034d1bb4c60743aef2faa065fa1f99?ds=sidebyside A first attempt at listening sockets in Open Transport. git-svn-id: svn://svn.tartarus.org/sgt/putty@5385 cda61777-01e9-0310-a592-d414129be87e --- diff --git a/mac/mac.h b/mac/mac.h index 8a0c7f13..8e73b7db 100644 --- a/mac/mac.h +++ b/mac/mac.h @@ -188,7 +188,7 @@ extern void mactcp_addrcopy(SockAddr, char *); extern void mactcp_addr_free(SockAddr); extern Socket mactcp_register(void *, Plug); extern Socket mactcp_new(SockAddr addr, int, int, int, int, int, Plug); -extern Socket mactcp_newlistener(char *, int, Plug, int); +extern Socket mactcp_newlistener(char *, int, Plug, int, int); extern char *mactcp_addr_error(SockAddr); /* from otnet.c */ extern OSErr ot_init(void); @@ -204,7 +204,7 @@ extern void ot_addrcopy(SockAddr, char *); extern void ot_addr_free(SockAddr); extern Socket ot_register(void *, Plug); extern Socket ot_new(SockAddr addr, int, int, int, int, int, Plug); -extern Socket ot_newlistener(char *, int, Plug, int); +extern Socket ot_newlistener(char *, int, Plug, int, int); extern char *ot_addr_error(SockAddr); /* from macabout.c */ extern void mac_openabout(void); diff --git a/mac/macnet.c b/mac/macnet.c index ddc3d77c..2ed0069b 100644 --- a/mac/macnet.c +++ b/mac/macnet.c @@ -14,7 +14,7 @@ struct macnet_stack { void (*addr_free)(SockAddr); Socket (*skregister)(void *, Plug); /* "register" is a reserved word */ Socket (*new)(SockAddr, int, int, int, int, int, Plug); - Socket (*newlistener)(char *, int, Plug, int); + Socket (*newlistener)(char *, int, Plug, int, int); char *(*addr_error)(SockAddr); void (*poll)(void); void (*cleanup)(void); @@ -142,7 +142,7 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only, i { if (stack != NULL) - return stack->newlistener(srcaddr, port, plug, local_host_only); + return stack->newlistener(srcaddr, port, plug, local_host_only, address_family); return NULL; } diff --git a/mac/macstore.c b/mac/macstore.c index 5b6afba2..35f31bdb 100644 --- a/mac/macstore.c +++ b/mac/macstore.c @@ -506,10 +506,10 @@ void *enum_settings_start(void) { OSErr error; struct enum_settings_state *state; - state = safemalloc(sizeof(*state)); + state = snew(struct enum_settings_state); error = get_session_dir(kDontCreateFolder, &state->vRefNum, &state->dirID); if (error != noErr) { - safefree(state); + sfree(state); return NULL; } state->index = 1; diff --git a/mac/mtcpnet.c b/mac/mtcpnet.c index 791557d2..c1c1fb80 100644 --- a/mac/mtcpnet.c +++ b/mac/mtcpnet.c @@ -523,7 +523,7 @@ Socket mactcp_new(SockAddr addr, int port, int privport, int oobinline, } Socket mactcp_newlistener(char *srcaddr, int port, Plug plug, - int local_host_only) + int local_host_only, int address_family) { fatalbox("mactcp_newlistener"); diff --git a/mac/otnet.c b/mac/otnet.c index 61c7fa50..6bdad502 100644 --- a/mac/otnet.c +++ b/mac/otnet.c @@ -187,6 +187,7 @@ static void *ot_tcp_get_private_ptr(Socket s); static void ot_tcp_set_frozen(Socket s, int is_frozen); static const char *ot_tcp_socket_error(Socket s); static void ot_recv(Actual_Socket s); +static void ot_listenaccept(Actual_Socket s); void ot_poll(void); Socket ot_register(void *sock, Plug plug) @@ -329,11 +330,79 @@ Socket ot_new(SockAddr addr, int port, int privport, int oobinline, return (Socket) ret; } -Socket ot_newlistener(char *foobar, int port, Plug plug, int local_host_only) +Socket ot_newlistener(char *srcaddr, int port, Plug plug, int local_host_only, + int address_family) { - Actual_Socket s; + static struct socket_function_table fn_table = { + ot_tcp_plug, + ot_tcp_close, + ot_tcp_write, + ot_tcp_write_oob, + ot_tcp_flush, + ot_tcp_set_private_ptr, + ot_tcp_get_private_ptr, + ot_tcp_set_frozen, + ot_tcp_socket_error + }; + + Actual_Socket ret; + EndpointRef ep; + OSStatus err; + InetAddress addr; + TBind tbind; + + ret = snew(struct Socket_tag); + ret->fn = &fn_table; + ret->error = kOTNoError; + ret->plug = plug; + bufchain_init(&ret->output_data); + ret->writable = 0; /* to start with */ + ret->sending_oob = 0; + ret->frozen = 0; + ret->frozen_readable = 0; + ret->localhost_only = local_host_only; + ret->pending_error = 0; + ret->oobinline = 0; + ret->oobpending = FALSE; + ret->listener = 1; + + /* Open Endpoint, configure it for TCP over anything, and load the + * tilisten module to serialize multiple simultaneous + * connections. */ + + ep = OTOpenEndpoint(OTCreateConfiguration("tilisten,tcp"), 0, NULL, &err); + + ret->ep = ep; + + if (err) { + ret->error = err; + return (Socket) ret; + } + + /* TODO: set SO_REUSEADDR */ + + OTInitInetAddress(&addr, port, kOTAnyInetAddress); + /* XXX: pay attention to local_host_only */ + + tbind.addr.buf = (UInt8 *) &addr; + tbind.addr.len = sizeof(addr); + tbind.qlen = 10; + + err = OTBind(ep, &tbind, NULL); /* XXX: check qlen we got */ + + if (err) { + ret->error = err; + return (Socket) ret; + } + + /* Add this to the list of all sockets */ + ret->next = ot.socklist; + ret->prev = &ot.socklist; + if (ret->next != NULL) + ret->next->prev = &ret->next; + ot.socklist = ret; - return (Socket) s; + return (Socket) ret; } static void ot_tcp_close(Socket sock) @@ -461,6 +530,9 @@ void ot_poll(void) case T_EXDATA: /* Expedited Data (urgent?) */ ot_recv(s); break; + case T_LISTEN: /* Connection attempt */ + ot_listenaccept(s); + break; } } } @@ -480,7 +552,36 @@ void ot_recv(Actual_Socket s) plug_closing(s->plug, NULL, 0, 0); /* XXX Error msg */ } +void ot_listenaccept(Actual_Socket s) +{ + OTResult o; + OSStatus err; + InetAddress remoteaddr; + TCall tcall; + EndpointRef ep; + + tcall.addr.maxlen = sizeof(InetAddress); + tcall.addr.buf = (unsigned char *)&remoteaddr; + tcall.opt.maxlen = 0; + tcall.opt.buf = NULL; + tcall.udata.maxlen = 0; + tcall.udata.buf = NULL; + o = OTListen(s->ep, &tcall); + + if (o != kOTNoError) + return; + + /* We've found an incoming connection, accept it */ + + ep = OTOpenEndpoint(OTCreateConfiguration("tcp"), 0, NULL, &err); + o = OTAccept(s->ep, ep, &tcall); + if (plug_accepting(s->plug, ep)) { + OTUnbind(ep); + OTCloseProvider(ep); + } +} + /* * Local Variables: * c-file-style: "simon"