summaryrefslogtreecommitdiff
path: root/dix/dispatch.c
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2011-06-17 13:43:38 -0400
committerAdam Jackson <ajax@redhat.com>2012-09-20 14:40:18 -0400
commite2c7d70e5ddb8b17676a13ceebfbb87d14d63243 (patch)
tree5e05955916a21f3d50c059eb38c90767924b6181 /dix/dispatch.c
parent31bf81772e146af79b0c456aae2159eba8b0280f (diff)
dix: Extend initial connection handshake for forwarding proxies
Forwarding proxies like sshd will appear to be local, even though they aren't really. This leads to weird behaviour for extensions that truly require running under the same OS services as the client, like MIT-SHM and DRI2. Add two new legal values for the initial connection's byteOrder field, 'r' and 'R'. These act like 'l' and 'B' respectively, but have the side effect of forcing the client to be treated as non-local. Forwarding proxies should attempt to munge the first packet of the connection accordingly; older servers will reject connections thusly munged, so the proxy should fall back to passthrough if the munged connection attempt fails. Reviewed-by: Daniel Stone <daniel@fooishbar.org> Signed-off-by: Adam Jackson <ajax@redhat.com>
Diffstat (limited to 'dix/dispatch.c')
-rw-r--r--dix/dispatch.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 0ce10c2f7..2df1a6ea5 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3499,14 +3499,16 @@ ProcInitialConnection(ClientPtr client)
REQUEST(xReq);
xConnClientPrefix *prefix;
int whichbyte = 1;
+ char order;
- prefix = (xConnClientPrefix *) ((char *) stuff + sz_xReq);
- if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
- return client->noClientException = -1;
- if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
- (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) {
- client->swapped = TRUE;
- SwapConnClientPrefix(prefix);
+ prefix = (xConnClientPrefix *) ((char *)stuff + sz_xReq);
+ order = prefix->byteOrder;
+ if (order != 'l' && order != 'B' && order != 'r' && order != 'R')
+ return client->noClientException = -1;
+ if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) ||
+ (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) {
+ client->swapped = TRUE;
+ SwapConnClientPrefix(prefix);
}
stuff->reqType = 2;
stuff->length += bytes_to_int32(prefix->nbytesAuthProto) +
@@ -3514,6 +3516,9 @@ ProcInitialConnection(ClientPtr client)
if (client->swapped) {
swaps(&stuff->length);
}
+ if (order == 'r' || order == 'R') {
+ client->local = FALSE;
+ }
ResetCurrentRequest(client);
return Success;
}