mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-01 11:32:48 -05:00
Modernise the Socket/Plug vtable system.
Now I've got FROMFIELD, I can rework it so that structures providing an implementation of the Socket or Plug trait no longer have to have the vtable pointer as the very first thing in the structure. In particular, this means that the ProxySocket structure can now directly implement _both_ the Socket and Plug traits, which is always _logically_ how it's worked, but previously it had to be implemented via two separate structs linked to each other.
This commit is contained in:
@ -312,7 +312,7 @@ int init_ucs(struct unicode_data *ucsdata, char *line_codepage,
|
||||
/*
|
||||
* Spare function exported directly from uxnet.c.
|
||||
*/
|
||||
void *sk_getxdmdata(void *sock, int *lenp);
|
||||
void *sk_getxdmdata(Socket sock, int *lenp);
|
||||
|
||||
/*
|
||||
* General helpful Unix stuff: more helpful version of the FD_SET
|
||||
|
189
unix/uxnet.c
189
unix/uxnet.c
@ -46,16 +46,6 @@ union sockaddr_union {
|
||||
struct sockaddr_un su;
|
||||
};
|
||||
|
||||
/*
|
||||
* We used to typedef struct Socket_tag *Socket.
|
||||
*
|
||||
* Since we have made the networking abstraction slightly more
|
||||
* abstract, Socket no longer means a tcp socket (it could mean
|
||||
* an ssl socket). So now we must use Actual_Socket when we know
|
||||
* we are talking about a tcp socket.
|
||||
*/
|
||||
typedef struct Socket_tag *Actual_Socket;
|
||||
|
||||
/*
|
||||
* Mutable state that goes with a SockAddr: stores information
|
||||
* about where in the list of candidate IP(v*) addresses we've
|
||||
@ -69,9 +59,8 @@ struct SockAddrStep_tag {
|
||||
int curraddr;
|
||||
};
|
||||
|
||||
struct Socket_tag {
|
||||
struct socket_function_table *fn;
|
||||
/* the above variable absolutely *must* be the first in this structure */
|
||||
typedef struct NetSocket NetSocket;
|
||||
struct NetSocket {
|
||||
const char *error;
|
||||
int s;
|
||||
Plug plug;
|
||||
@ -98,7 +87,9 @@ struct Socket_tag {
|
||||
* example. So here we define `parent' and `child' pointers to
|
||||
* track this link.
|
||||
*/
|
||||
Actual_Socket parent, child;
|
||||
NetSocket *parent, *child;
|
||||
|
||||
const Socket_vtable *sockvt;
|
||||
};
|
||||
|
||||
struct SockAddr_tag {
|
||||
@ -148,11 +139,11 @@ struct SockAddr_tag {
|
||||
|
||||
static tree234 *sktree;
|
||||
|
||||
static void uxsel_tell(Actual_Socket s);
|
||||
static void uxsel_tell(NetSocket *s);
|
||||
|
||||
static int cmpfortree(void *av, void *bv)
|
||||
{
|
||||
Actual_Socket a = (Actual_Socket) av, b = (Actual_Socket) bv;
|
||||
NetSocket *a = (NetSocket *) av, *b = (NetSocket *) bv;
|
||||
int as = a->s, bs = b->s;
|
||||
if (as < bs)
|
||||
return -1;
|
||||
@ -167,7 +158,7 @@ static int cmpfortree(void *av, void *bv)
|
||||
|
||||
static int cmpforsearch(void *av, void *bv)
|
||||
{
|
||||
Actual_Socket b = (Actual_Socket) bv;
|
||||
NetSocket *b = (NetSocket *) bv;
|
||||
int as = *(int *)av, bs = b->s;
|
||||
if (as < bs)
|
||||
return -1;
|
||||
@ -183,7 +174,7 @@ void sk_init(void)
|
||||
|
||||
void sk_cleanup(void)
|
||||
{
|
||||
Actual_Socket s;
|
||||
NetSocket *s;
|
||||
int i;
|
||||
|
||||
if (sktree) {
|
||||
@ -491,16 +482,16 @@ SockAddr sk_addr_dup(SockAddr addr)
|
||||
return addr;
|
||||
}
|
||||
|
||||
static Plug sk_tcp_plug(Socket sock, Plug p)
|
||||
static Plug sk_net_plug(Socket sock, Plug p)
|
||||
{
|
||||
Actual_Socket s = (Actual_Socket) sock;
|
||||
NetSocket *s = FROMFIELD(sock, NetSocket, sockvt);
|
||||
Plug ret = s->plug;
|
||||
if (p)
|
||||
s->plug = p;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sk_tcp_flush(Socket s)
|
||||
static void sk_net_flush(Socket s)
|
||||
{
|
||||
/*
|
||||
* We send data to the socket as soon as we can anyway,
|
||||
@ -508,36 +499,36 @@ static void sk_tcp_flush(Socket s)
|
||||
*/
|
||||
}
|
||||
|
||||
static void sk_tcp_close(Socket s);
|
||||
static int sk_tcp_write(Socket s, const void *data, int len);
|
||||
static int sk_tcp_write_oob(Socket s, const void *data, int len);
|
||||
static void sk_tcp_write_eof(Socket s);
|
||||
static void sk_tcp_set_frozen(Socket s, int is_frozen);
|
||||
static char *sk_tcp_peer_info(Socket s);
|
||||
static const char *sk_tcp_socket_error(Socket s);
|
||||
static void sk_net_close(Socket s);
|
||||
static int sk_net_write(Socket s, const void *data, int len);
|
||||
static int sk_net_write_oob(Socket s, const void *data, int len);
|
||||
static void sk_net_write_eof(Socket s);
|
||||
static void sk_net_set_frozen(Socket s, int is_frozen);
|
||||
static char *sk_net_peer_info(Socket s);
|
||||
static const char *sk_net_socket_error(Socket s);
|
||||
|
||||
static struct socket_function_table tcp_fn_table = {
|
||||
sk_tcp_plug,
|
||||
sk_tcp_close,
|
||||
sk_tcp_write,
|
||||
sk_tcp_write_oob,
|
||||
sk_tcp_write_eof,
|
||||
sk_tcp_flush,
|
||||
sk_tcp_set_frozen,
|
||||
sk_tcp_socket_error,
|
||||
sk_tcp_peer_info,
|
||||
static struct Socket_vtable NetSocket_sockvt = {
|
||||
sk_net_plug,
|
||||
sk_net_close,
|
||||
sk_net_write,
|
||||
sk_net_write_oob,
|
||||
sk_net_write_eof,
|
||||
sk_net_flush,
|
||||
sk_net_set_frozen,
|
||||
sk_net_socket_error,
|
||||
sk_net_peer_info,
|
||||
};
|
||||
|
||||
static Socket sk_tcp_accept(accept_ctx_t ctx, Plug plug)
|
||||
static Socket sk_net_accept(accept_ctx_t ctx, Plug plug)
|
||||
{
|
||||
int sockfd = ctx.i;
|
||||
Actual_Socket ret;
|
||||
NetSocket *ret;
|
||||
|
||||
/*
|
||||
* Create Socket structure.
|
||||
* Create NetSocket structure.
|
||||
*/
|
||||
ret = snew(struct Socket_tag);
|
||||
ret->fn = &tcp_fn_table;
|
||||
ret = snew(NetSocket);
|
||||
ret->sockvt = &NetSocket_sockvt;
|
||||
ret->error = NULL;
|
||||
ret->plug = plug;
|
||||
bufchain_init(&ret->output_data);
|
||||
@ -558,7 +549,7 @@ static Socket sk_tcp_accept(accept_ctx_t ctx, Plug plug)
|
||||
|
||||
if (ret->s < 0) {
|
||||
ret->error = strerror(errno);
|
||||
return (Socket) ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
|
||||
ret->oobinline = 0;
|
||||
@ -566,10 +557,10 @@ static Socket sk_tcp_accept(accept_ctx_t ctx, Plug plug)
|
||||
uxsel_tell(ret);
|
||||
add234(sktree, ret);
|
||||
|
||||
return (Socket) ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
|
||||
static int try_connect(Actual_Socket sock)
|
||||
static int try_connect(NetSocket *sock)
|
||||
{
|
||||
int s;
|
||||
union sockaddr_union u;
|
||||
@ -771,14 +762,14 @@ static int try_connect(Actual_Socket sock)
|
||||
Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
||||
int nodelay, int keepalive, Plug plug)
|
||||
{
|
||||
Actual_Socket ret;
|
||||
NetSocket *ret;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* Create Socket structure.
|
||||
* Create NetSocket structure.
|
||||
*/
|
||||
ret = snew(struct Socket_tag);
|
||||
ret->fn = &tcp_fn_table;
|
||||
ret = snew(NetSocket);
|
||||
ret->sockvt = &NetSocket_sockvt;
|
||||
ret->error = NULL;
|
||||
ret->plug = plug;
|
||||
bufchain_init(&ret->output_data);
|
||||
@ -810,7 +801,7 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
||||
if (err)
|
||||
ret->error = strerror(err);
|
||||
|
||||
return (Socket) ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
|
||||
Socket sk_newlistener(const char *srcaddr, int port, Plug plug,
|
||||
@ -824,16 +815,16 @@ Socket sk_newlistener(const char *srcaddr, int port, Plug plug,
|
||||
union sockaddr_union u;
|
||||
union sockaddr_union *addr;
|
||||
int addrlen;
|
||||
Actual_Socket ret;
|
||||
NetSocket *ret;
|
||||
int retcode;
|
||||
int address_family;
|
||||
int on = 1;
|
||||
|
||||
/*
|
||||
* Create Socket structure.
|
||||
* Create NetSocket structure.
|
||||
*/
|
||||
ret = snew(struct Socket_tag);
|
||||
ret->fn = &tcp_fn_table;
|
||||
ret = snew(NetSocket);
|
||||
ret->sockvt = &NetSocket_sockvt;
|
||||
ret->error = NULL;
|
||||
ret->plug = plug;
|
||||
bufchain_init(&ret->output_data);
|
||||
@ -884,7 +875,7 @@ Socket sk_newlistener(const char *srcaddr, int port, Plug plug,
|
||||
|
||||
if (s < 0) {
|
||||
ret->error = strerror(errno);
|
||||
return (Socket) ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
|
||||
cloexec(s);
|
||||
@ -895,7 +886,7 @@ Socket sk_newlistener(const char *srcaddr, int port, Plug plug,
|
||||
(const char *)&on, sizeof(on)) < 0) {
|
||||
ret->error = strerror(errno);
|
||||
close(s);
|
||||
return (Socket) ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
|
||||
retcode = -1;
|
||||
@ -973,13 +964,13 @@ Socket sk_newlistener(const char *srcaddr, int port, Plug plug,
|
||||
if (retcode < 0) {
|
||||
close(s);
|
||||
ret->error = strerror(errno);
|
||||
return (Socket) ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
|
||||
if (listen(s, SOMAXCONN) < 0) {
|
||||
close(s);
|
||||
ret->error = strerror(errno);
|
||||
return (Socket) ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
|
||||
#ifndef NO_IPV6
|
||||
@ -988,10 +979,12 @@ Socket sk_newlistener(const char *srcaddr, int port, Plug plug,
|
||||
* IPv4 listening socket and link it to this one.
|
||||
*/
|
||||
if (address_family == AF_INET6 && orig_address_family == ADDRTYPE_UNSPEC) {
|
||||
Actual_Socket other;
|
||||
NetSocket *other;
|
||||
|
||||
other = (Actual_Socket) sk_newlistener(srcaddr, port, plug,
|
||||
local_host_only, ADDRTYPE_IPV4);
|
||||
other = FROMFIELD(
|
||||
sk_newlistener(srcaddr, port, plug,
|
||||
local_host_only, ADDRTYPE_IPV4),
|
||||
NetSocket, sockvt);
|
||||
|
||||
if (other) {
|
||||
if (!other->error) {
|
||||
@ -1002,7 +995,7 @@ Socket sk_newlistener(const char *srcaddr, int port, Plug plug,
|
||||
* as IPv6, we must return an error overall. */
|
||||
close(s);
|
||||
sfree(ret);
|
||||
return (Socket) other;
|
||||
return &other->sockvt;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1013,15 +1006,15 @@ Socket sk_newlistener(const char *srcaddr, int port, Plug plug,
|
||||
uxsel_tell(ret);
|
||||
add234(sktree, ret);
|
||||
|
||||
return (Socket) ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
|
||||
static void sk_tcp_close(Socket sock)
|
||||
static void sk_net_close(Socket sock)
|
||||
{
|
||||
Actual_Socket s = (Actual_Socket) sock;
|
||||
NetSocket *s = FROMFIELD(sock, NetSocket, sockvt);
|
||||
|
||||
if (s->child)
|
||||
sk_tcp_close((Socket)s->child);
|
||||
sk_net_close(&s->child->sockvt);
|
||||
|
||||
del234(sktree, s);
|
||||
if (s->s >= 0) {
|
||||
@ -1033,19 +1026,21 @@ static void sk_tcp_close(Socket sock)
|
||||
sfree(s);
|
||||
}
|
||||
|
||||
void *sk_getxdmdata(void *sock, int *lenp)
|
||||
void *sk_getxdmdata(Socket sock, int *lenp)
|
||||
{
|
||||
Actual_Socket s = (Actual_Socket) sock;
|
||||
NetSocket *s;
|
||||
union sockaddr_union u;
|
||||
socklen_t addrlen;
|
||||
char *buf;
|
||||
static unsigned int unix_addr = 0xFFFFFFFF;
|
||||
|
||||
/*
|
||||
* We must check that this socket really _is_ an Actual_Socket.
|
||||
* We must check that this socket really _is_ a NetSocket before
|
||||
* downcasting it.
|
||||
*/
|
||||
if (s->fn != &tcp_fn_table)
|
||||
if (*sock != &NetSocket_sockvt)
|
||||
return NULL; /* failure */
|
||||
s = FROMFIELD(sock, NetSocket, sockvt);
|
||||
|
||||
addrlen = sizeof(u);
|
||||
if (getsockname(s->s, &u.sa, &addrlen) < 0)
|
||||
@ -1090,7 +1085,7 @@ void *sk_getxdmdata(void *sock, int *lenp)
|
||||
*/
|
||||
static void socket_error_callback(void *vs)
|
||||
{
|
||||
Actual_Socket s = (Actual_Socket)vs;
|
||||
NetSocket *s = (NetSocket *)vs;
|
||||
|
||||
/*
|
||||
* Just in case other socket work has caused this socket to vanish
|
||||
@ -1109,7 +1104,7 @@ static void socket_error_callback(void *vs)
|
||||
* The function which tries to send on a socket once it's deemed
|
||||
* writable.
|
||||
*/
|
||||
void try_send(Actual_Socket s)
|
||||
void try_send(NetSocket *s)
|
||||
{
|
||||
while (s->sending_oob || bufchain_size(&s->output_data) > 0) {
|
||||
int nsent;
|
||||
@ -1189,9 +1184,9 @@ void try_send(Actual_Socket s)
|
||||
uxsel_tell(s);
|
||||
}
|
||||
|
||||
static int sk_tcp_write(Socket sock, const void *buf, int len)
|
||||
static int sk_net_write(Socket sock, const void *buf, int len)
|
||||
{
|
||||
Actual_Socket s = (Actual_Socket) sock;
|
||||
NetSocket *s = FROMFIELD(sock, NetSocket, sockvt);
|
||||
|
||||
assert(s->outgoingeof == EOF_NO);
|
||||
|
||||
@ -1215,9 +1210,9 @@ static int sk_tcp_write(Socket sock, const void *buf, int len)
|
||||
return bufchain_size(&s->output_data);
|
||||
}
|
||||
|
||||
static int sk_tcp_write_oob(Socket sock, const void *buf, int len)
|
||||
static int sk_net_write_oob(Socket sock, const void *buf, int len)
|
||||
{
|
||||
Actual_Socket s = (Actual_Socket) sock;
|
||||
NetSocket *s = FROMFIELD(sock, NetSocket, sockvt);
|
||||
|
||||
assert(s->outgoingeof == EOF_NO);
|
||||
|
||||
@ -1244,9 +1239,9 @@ static int sk_tcp_write_oob(Socket sock, const void *buf, int len)
|
||||
return s->sending_oob;
|
||||
}
|
||||
|
||||
static void sk_tcp_write_eof(Socket sock)
|
||||
static void sk_net_write_eof(Socket sock)
|
||||
{
|
||||
Actual_Socket s = (Actual_Socket) sock;
|
||||
NetSocket *s = FROMFIELD(sock, NetSocket, sockvt);
|
||||
|
||||
assert(s->outgoingeof == EOF_NO);
|
||||
|
||||
@ -1272,7 +1267,7 @@ static void net_select_result(int fd, int event)
|
||||
{
|
||||
int ret;
|
||||
char buf[20480]; /* nice big buffer for plenty of speed */
|
||||
Actual_Socket s;
|
||||
NetSocket *s;
|
||||
u_long atmark;
|
||||
|
||||
/* Find the Socket structure */
|
||||
@ -1343,7 +1338,7 @@ static void net_select_result(int fd, int event)
|
||||
if ((!s->addr || s->addr->superfamily != UNIX) &&
|
||||
s->localhost_only && !sockaddr_is_loopback(&su.sa)) {
|
||||
close(t); /* someone let nonlocal through?! */
|
||||
} else if (plug_accepting(s->plug, sk_tcp_accept, actx)) {
|
||||
} else if (plug_accepting(s->plug, sk_net_accept, actx)) {
|
||||
close(t); /* denied or error */
|
||||
}
|
||||
break;
|
||||
@ -1471,24 +1466,24 @@ const char *sk_addr_error(SockAddr addr)
|
||||
{
|
||||
return addr->error;
|
||||
}
|
||||
static const char *sk_tcp_socket_error(Socket sock)
|
||||
static const char *sk_net_socket_error(Socket sock)
|
||||
{
|
||||
Actual_Socket s = (Actual_Socket) sock;
|
||||
NetSocket *s = FROMFIELD(sock, NetSocket, sockvt);
|
||||
return s->error;
|
||||
}
|
||||
|
||||
static void sk_tcp_set_frozen(Socket sock, int is_frozen)
|
||||
static void sk_net_set_frozen(Socket sock, int is_frozen)
|
||||
{
|
||||
Actual_Socket s = (Actual_Socket) sock;
|
||||
NetSocket *s = FROMFIELD(sock, NetSocket, sockvt);
|
||||
if (s->frozen == is_frozen)
|
||||
return;
|
||||
s->frozen = is_frozen;
|
||||
uxsel_tell(s);
|
||||
}
|
||||
|
||||
static char *sk_tcp_peer_info(Socket sock)
|
||||
static char *sk_net_peer_info(Socket sock)
|
||||
{
|
||||
Actual_Socket s = (Actual_Socket) sock;
|
||||
NetSocket *s = FROMFIELD(sock, NetSocket, sockvt);
|
||||
union sockaddr_union addr;
|
||||
socklen_t addrlen = sizeof(addr);
|
||||
#ifndef NO_IPV6
|
||||
@ -1532,7 +1527,7 @@ static char *sk_tcp_peer_info(Socket sock)
|
||||
}
|
||||
}
|
||||
|
||||
static void uxsel_tell(Actual_Socket s)
|
||||
static void uxsel_tell(NetSocket *s)
|
||||
{
|
||||
int rwx = 0;
|
||||
if (!s->pending_error) {
|
||||
@ -1642,14 +1637,14 @@ Socket new_unix_listener(SockAddr listenaddr, Plug plug)
|
||||
union sockaddr_union u;
|
||||
union sockaddr_union *addr;
|
||||
int addrlen;
|
||||
Actual_Socket ret;
|
||||
NetSocket *ret;
|
||||
int retcode;
|
||||
|
||||
/*
|
||||
* Create Socket structure.
|
||||
* Create NetSocket structure.
|
||||
*/
|
||||
ret = snew(struct Socket_tag);
|
||||
ret->fn = &tcp_fn_table;
|
||||
ret = snew(NetSocket);
|
||||
ret->sockvt = &NetSocket_sockvt;
|
||||
ret->error = NULL;
|
||||
ret->plug = plug;
|
||||
bufchain_init(&ret->output_data);
|
||||
@ -1674,7 +1669,7 @@ Socket new_unix_listener(SockAddr listenaddr, Plug plug)
|
||||
s = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
ret->error = strerror(errno);
|
||||
return (Socket) ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
|
||||
cloexec(s);
|
||||
@ -1690,20 +1685,20 @@ Socket new_unix_listener(SockAddr listenaddr, Plug plug)
|
||||
if (unlink(u.su.sun_path) < 0 && errno != ENOENT) {
|
||||
close(s);
|
||||
ret->error = strerror(errno);
|
||||
return (Socket) ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
|
||||
retcode = bind(s, &addr->sa, addrlen);
|
||||
if (retcode < 0) {
|
||||
close(s);
|
||||
ret->error = strerror(errno);
|
||||
return (Socket) ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
|
||||
if (listen(s, SOMAXCONN) < 0) {
|
||||
close(s);
|
||||
ret->error = strerror(errno);
|
||||
return (Socket) ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
|
||||
ret->s = s;
|
||||
@ -1711,5 +1706,5 @@ Socket new_unix_listener(SockAddr listenaddr, Plug plug)
|
||||
uxsel_tell(ret);
|
||||
add234(sktree, ret);
|
||||
|
||||
return (Socket) ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ static void x11_closing(Plug plug, const char *error_msg, int error_code,
|
||||
time_to_die = TRUE;
|
||||
}
|
||||
struct X11Connection {
|
||||
const struct plug_function_table *fn;
|
||||
const Plug_vtable *plugvt;
|
||||
};
|
||||
|
||||
char *socketname;
|
||||
@ -735,11 +735,20 @@ void run_client(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static const Plug_vtable X11Connection_plugvt = {
|
||||
x11_log,
|
||||
x11_closing,
|
||||
x11_receive,
|
||||
x11_sent,
|
||||
NULL
|
||||
};
|
||||
|
||||
void run_agent(void)
|
||||
{
|
||||
const char *err;
|
||||
char *username, *socketdir;
|
||||
struct pageant_listen_state *pl;
|
||||
Plug pl_plug;
|
||||
Socket sock;
|
||||
unsigned long now;
|
||||
int *fdlist;
|
||||
@ -778,8 +787,8 @@ void run_agent(void)
|
||||
exit(1);
|
||||
}
|
||||
socketname = dupprintf("%s/pageant.%d", socketdir, (int)getpid());
|
||||
pl = pageant_listener_new();
|
||||
sock = new_unix_listener(unix_sock_addr(socketname), (Plug)pl);
|
||||
pl = pageant_listener_new(&pl_plug);
|
||||
sock = new_unix_listener(unix_sock_addr(socketname), pl_plug);
|
||||
if ((err = sk_socket_error(sock)) != NULL) {
|
||||
fprintf(stderr, "pageant: %s: %s\n", socketname, err);
|
||||
exit(1);
|
||||
@ -800,14 +809,6 @@ void run_agent(void)
|
||||
Socket s;
|
||||
struct X11Connection *conn;
|
||||
|
||||
static const struct plug_function_table fn_table = {
|
||||
x11_log,
|
||||
x11_closing,
|
||||
x11_receive,
|
||||
x11_sent,
|
||||
NULL
|
||||
};
|
||||
|
||||
if (!display) {
|
||||
fprintf(stderr, "pageant: no DISPLAY for -X mode\n");
|
||||
exit(1);
|
||||
@ -815,10 +816,10 @@ void run_agent(void)
|
||||
disp = x11_setup_display(display, conf);
|
||||
|
||||
conn = snew(struct X11Connection);
|
||||
conn->fn = &fn_table;
|
||||
conn->plugvt = &X11Connection_plugvt;
|
||||
s = new_connection(sk_addr_dup(disp->addr),
|
||||
disp->realhost, disp->port,
|
||||
0, 1, 0, 0, (Plug)conn, conf);
|
||||
0, 1, 0, 0, &conn->plugvt, conf);
|
||||
if ((err = sk_socket_error(s)) != NULL) {
|
||||
fprintf(stderr, "pageant: unable to connect to X server: %s", err);
|
||||
exit(1);
|
||||
|
@ -15,12 +15,7 @@
|
||||
#include "network.h"
|
||||
#include "proxy.h"
|
||||
|
||||
typedef struct Socket_localproxy_tag * Local_Proxy_Socket;
|
||||
|
||||
struct Socket_localproxy_tag {
|
||||
const struct socket_function_table *fn;
|
||||
/* the above variable absolutely *must* be the first in this structure */
|
||||
|
||||
typedef struct LocalProxySocket {
|
||||
int to_cmd, from_cmd, cmd_err; /* fds */
|
||||
|
||||
char *error;
|
||||
@ -31,7 +26,9 @@ struct Socket_localproxy_tag {
|
||||
bufchain pending_input_data;
|
||||
bufchain pending_error_data;
|
||||
enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof;
|
||||
};
|
||||
|
||||
const Socket_vtable *sockvt;
|
||||
} LocalProxySocket;
|
||||
|
||||
static void localproxy_select_result(int fd, int event);
|
||||
|
||||
@ -43,8 +40,8 @@ static tree234 *localproxy_by_tofd;
|
||||
static tree234 *localproxy_by_errfd;
|
||||
static int localproxy_fromfd_cmp(void *av, void *bv)
|
||||
{
|
||||
Local_Proxy_Socket a = (Local_Proxy_Socket)av;
|
||||
Local_Proxy_Socket b = (Local_Proxy_Socket)bv;
|
||||
LocalProxySocket *a = (LocalProxySocket *)av;
|
||||
LocalProxySocket *b = (LocalProxySocket *)bv;
|
||||
if (a->from_cmd < b->from_cmd)
|
||||
return -1;
|
||||
if (a->from_cmd > b->from_cmd)
|
||||
@ -54,7 +51,7 @@ static int localproxy_fromfd_cmp(void *av, void *bv)
|
||||
static int localproxy_fromfd_find(void *av, void *bv)
|
||||
{
|
||||
int a = *(int *)av;
|
||||
Local_Proxy_Socket b = (Local_Proxy_Socket)bv;
|
||||
LocalProxySocket *b = (LocalProxySocket *)bv;
|
||||
if (a < b->from_cmd)
|
||||
return -1;
|
||||
if (a > b->from_cmd)
|
||||
@ -63,8 +60,8 @@ static int localproxy_fromfd_find(void *av, void *bv)
|
||||
}
|
||||
static int localproxy_tofd_cmp(void *av, void *bv)
|
||||
{
|
||||
Local_Proxy_Socket a = (Local_Proxy_Socket)av;
|
||||
Local_Proxy_Socket b = (Local_Proxy_Socket)bv;
|
||||
LocalProxySocket *a = (LocalProxySocket *)av;
|
||||
LocalProxySocket *b = (LocalProxySocket *)bv;
|
||||
if (a->to_cmd < b->to_cmd)
|
||||
return -1;
|
||||
if (a->to_cmd > b->to_cmd)
|
||||
@ -74,7 +71,7 @@ static int localproxy_tofd_cmp(void *av, void *bv)
|
||||
static int localproxy_tofd_find(void *av, void *bv)
|
||||
{
|
||||
int a = *(int *)av;
|
||||
Local_Proxy_Socket b = (Local_Proxy_Socket)bv;
|
||||
LocalProxySocket *b = (LocalProxySocket *)bv;
|
||||
if (a < b->to_cmd)
|
||||
return -1;
|
||||
if (a > b->to_cmd)
|
||||
@ -83,8 +80,8 @@ static int localproxy_tofd_find(void *av, void *bv)
|
||||
}
|
||||
static int localproxy_errfd_cmp(void *av, void *bv)
|
||||
{
|
||||
Local_Proxy_Socket a = (Local_Proxy_Socket)av;
|
||||
Local_Proxy_Socket b = (Local_Proxy_Socket)bv;
|
||||
LocalProxySocket *a = (LocalProxySocket *)av;
|
||||
LocalProxySocket *b = (LocalProxySocket *)bv;
|
||||
if (a->cmd_err < b->cmd_err)
|
||||
return -1;
|
||||
if (a->cmd_err > b->cmd_err)
|
||||
@ -94,7 +91,7 @@ static int localproxy_errfd_cmp(void *av, void *bv)
|
||||
static int localproxy_errfd_find(void *av, void *bv)
|
||||
{
|
||||
int a = *(int *)av;
|
||||
Local_Proxy_Socket b = (Local_Proxy_Socket)bv;
|
||||
LocalProxySocket *b = (LocalProxySocket *)bv;
|
||||
if (a < b->cmd_err)
|
||||
return -1;
|
||||
if (a > b->cmd_err)
|
||||
@ -106,7 +103,7 @@ static int localproxy_errfd_find(void *av, void *bv)
|
||||
|
||||
static Plug sk_localproxy_plug (Socket s, Plug p)
|
||||
{
|
||||
Local_Proxy_Socket ps = (Local_Proxy_Socket) s;
|
||||
LocalProxySocket *ps = FROMFIELD(s, LocalProxySocket, sockvt);
|
||||
Plug ret = ps->plug;
|
||||
if (p)
|
||||
ps->plug = p;
|
||||
@ -115,7 +112,7 @@ static Plug sk_localproxy_plug (Socket s, Plug p)
|
||||
|
||||
static void sk_localproxy_close (Socket s)
|
||||
{
|
||||
Local_Proxy_Socket ps = (Local_Proxy_Socket) s;
|
||||
LocalProxySocket *ps = FROMFIELD(s, LocalProxySocket, sockvt);
|
||||
|
||||
if (ps->to_cmd >= 0) {
|
||||
del234(localproxy_by_tofd, ps);
|
||||
@ -138,7 +135,7 @@ static void sk_localproxy_close (Socket s)
|
||||
sfree(ps);
|
||||
}
|
||||
|
||||
static int localproxy_try_send(Local_Proxy_Socket ps)
|
||||
static int localproxy_try_send(LocalProxySocket *ps)
|
||||
{
|
||||
int sent = 0;
|
||||
|
||||
@ -177,7 +174,7 @@ static int localproxy_try_send(Local_Proxy_Socket ps)
|
||||
|
||||
static int sk_localproxy_write (Socket s, const void *data, int len)
|
||||
{
|
||||
Local_Proxy_Socket ps = (Local_Proxy_Socket) s;
|
||||
LocalProxySocket *ps = FROMFIELD(s, LocalProxySocket, sockvt);
|
||||
|
||||
assert(ps->outgoingeof == EOF_NO);
|
||||
|
||||
@ -199,7 +196,7 @@ static int sk_localproxy_write_oob (Socket s, const void *data, int len)
|
||||
|
||||
static void sk_localproxy_write_eof (Socket s)
|
||||
{
|
||||
Local_Proxy_Socket ps = (Local_Proxy_Socket) s;
|
||||
LocalProxySocket *ps = FROMFIELD(s, LocalProxySocket, sockvt);
|
||||
|
||||
assert(ps->outgoingeof == EOF_NO);
|
||||
ps->outgoingeof = EOF_PENDING;
|
||||
@ -209,13 +206,13 @@ static void sk_localproxy_write_eof (Socket s)
|
||||
|
||||
static void sk_localproxy_flush (Socket s)
|
||||
{
|
||||
/* Local_Proxy_Socket ps = (Local_Proxy_Socket) s; */
|
||||
/* LocalProxySocket *ps = FROMFIELD(s, LocalProxySocket, sockvt); */
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
static void sk_localproxy_set_frozen (Socket s, int is_frozen)
|
||||
{
|
||||
Local_Proxy_Socket ps = (Local_Proxy_Socket) s;
|
||||
LocalProxySocket *ps = FROMFIELD(s, LocalProxySocket, sockvt);
|
||||
|
||||
if (is_frozen)
|
||||
uxsel_del(ps->from_cmd);
|
||||
@ -225,13 +222,13 @@ static void sk_localproxy_set_frozen (Socket s, int is_frozen)
|
||||
|
||||
static const char * sk_localproxy_socket_error (Socket s)
|
||||
{
|
||||
Local_Proxy_Socket ps = (Local_Proxy_Socket) s;
|
||||
LocalProxySocket *ps = FROMFIELD(s, LocalProxySocket, sockvt);
|
||||
return ps->error;
|
||||
}
|
||||
|
||||
static void localproxy_select_result(int fd, int event)
|
||||
{
|
||||
Local_Proxy_Socket s;
|
||||
LocalProxySocket *s;
|
||||
char buf[20480];
|
||||
int ret;
|
||||
|
||||
@ -263,6 +260,18 @@ static void localproxy_select_result(int fd, int event)
|
||||
}
|
||||
}
|
||||
|
||||
static const Socket_vtable LocalProxySocket_sockvt = {
|
||||
sk_localproxy_plug,
|
||||
sk_localproxy_close,
|
||||
sk_localproxy_write,
|
||||
sk_localproxy_write_oob,
|
||||
sk_localproxy_write_eof,
|
||||
sk_localproxy_flush,
|
||||
sk_localproxy_set_frozen,
|
||||
sk_localproxy_socket_error,
|
||||
NULL, /* peer_info */
|
||||
};
|
||||
|
||||
Socket platform_new_connection(SockAddr addr, const char *hostname,
|
||||
int port, int privport,
|
||||
int oobinline, int nodelay, int keepalive,
|
||||
@ -270,27 +279,15 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
|
||||
{
|
||||
char *cmd;
|
||||
|
||||
static const struct socket_function_table socket_fn_table = {
|
||||
sk_localproxy_plug,
|
||||
sk_localproxy_close,
|
||||
sk_localproxy_write,
|
||||
sk_localproxy_write_oob,
|
||||
sk_localproxy_write_eof,
|
||||
sk_localproxy_flush,
|
||||
sk_localproxy_set_frozen,
|
||||
sk_localproxy_socket_error,
|
||||
NULL, /* peer_info */
|
||||
};
|
||||
|
||||
Local_Proxy_Socket ret;
|
||||
LocalProxySocket *ret;
|
||||
int to_cmd_pipe[2], from_cmd_pipe[2], cmd_err_pipe[2], pid, proxytype;
|
||||
|
||||
proxytype = conf_get_int(conf, CONF_proxy_type);
|
||||
if (proxytype != PROXY_CMD && proxytype != PROXY_FUZZ)
|
||||
return NULL;
|
||||
|
||||
ret = snew(struct Socket_localproxy_tag);
|
||||
ret->fn = &socket_fn_table;
|
||||
ret = snew(LocalProxySocket);
|
||||
ret->sockvt = &LocalProxySocket_sockvt;
|
||||
ret->plug = plug;
|
||||
ret->error = NULL;
|
||||
ret->outgoingeof = EOF_NO;
|
||||
@ -329,7 +326,7 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
|
||||
(cmd_err_pipe[0] == 0 && pipe(cmd_err_pipe) < 0)) {
|
||||
ret->error = dupprintf("pipe: %s", strerror(errno));
|
||||
sfree(cmd);
|
||||
return (Socket)ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
cloexec(to_cmd_pipe[1]);
|
||||
cloexec(from_cmd_pipe[0]);
|
||||
@ -341,7 +338,7 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
|
||||
if (pid < 0) {
|
||||
ret->error = dupprintf("fork: %s", strerror(errno));
|
||||
sfree(cmd);
|
||||
return (Socket)ret;
|
||||
return &ret->sockvt;
|
||||
} else if (pid == 0) {
|
||||
close(0);
|
||||
close(1);
|
||||
@ -375,13 +372,13 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
|
||||
if (ret->to_cmd == -1) {
|
||||
ret->error = dupprintf("/dev/null: %s", strerror(errno));
|
||||
sfree(cmd);
|
||||
return (Socket)ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
ret->from_cmd = open(cmd, O_RDONLY);
|
||||
if (ret->from_cmd == -1) {
|
||||
ret->error = dupprintf("%s: %s", cmd, strerror(errno));
|
||||
sfree(cmd);
|
||||
return (Socket)ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
sfree(cmd);
|
||||
ret->cmd_err = -1;
|
||||
@ -406,5 +403,5 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
|
||||
/* We are responsible for this and don't need it any more */
|
||||
sk_addr_free(addr);
|
||||
|
||||
return (Socket) ret;
|
||||
return &ret->sockvt;
|
||||
}
|
||||
|
Reference in New Issue
Block a user