Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib Have the client and server perform some sort of handshak...
details: https://anonhg.NetBSD.org/src/rev/45f58de3cdcb
branches: trunk
changeset: 759782:45f58de3cdcb
user: pooka <pooka%NetBSD.org@localhost>
date: Thu Dec 16 17:05:44 2010 +0000
description:
Have the client and server perform some sort of handshake first.
It's pretty much a placeholder for now. One plan for the future
is to require some sort of authentication for superuser clients.
The code will need a little massage then, though, to prevent DoS
attacks.
diffstat:
lib/librumpclient/rumpclient.c | 65 +++++++++++++++++++++++++++++++++--------
lib/librumpuser/rumpuser_sp.c | 49 +++++++++++++++++++++++++++---
lib/librumpuser/sp_common.c | 22 ++++++++++---
3 files changed, 111 insertions(+), 25 deletions(-)
diffs (280 lines):
diff -r 112059144b1e -r 45f58de3cdcb lib/librumpclient/rumpclient.c
--- a/lib/librumpclient/rumpclient.c Thu Dec 16 16:59:05 2010 +0000
+++ b/lib/librumpclient/rumpclient.c Thu Dec 16 17:05:44 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpclient.c,v 1.9 2010/12/16 12:38:21 pooka Exp $ */
+/* $NetBSD: rumpclient.c,v 1.10 2010/12/16 17:05:44 pooka Exp $ */
/*
* Copyright (c) 2010 Antti Kantee. All Rights Reserved.
@@ -87,6 +87,36 @@
}
static int
+handshake_req(struct spclient *spc)
+{
+ struct rsp_hdr rhdr;
+ struct respwait rw;
+ int rv;
+
+ /* performs server handshake */
+ rhdr.rsp_len = sizeof(rhdr);
+ rhdr.rsp_class = RUMPSP_REQ;
+ rhdr.rsp_type = RUMPSP_HANDSHAKE;
+ rhdr.rsp_handshake = HANDSHAKE_GUEST;
+
+ putwait(spc, &rw, &rhdr);
+ rv = dosend(spc, &rhdr, sizeof(rhdr));
+ if (rv != 0) {
+ unputwait(spc, &rw);
+ return rv;
+ }
+
+ rv = waitresp(spc, &rw);
+ if (rv)
+ return rv;
+
+ rv = *(int *)rw.rw_data;
+ free(rw.rw_data);
+
+ return rv;
+}
+
+static int
send_copyin_resp(struct spclient *spc, uint64_t reqno, void *data, size_t dlen,
int wantstr)
{
@@ -235,21 +265,12 @@
return -1;
}
- if ((error = parsetab[idx].connhook(s)) != 0) {
+ if ((n = read(s, banner, sizeof(banner)-1)) < 0) {
error = errno;
- fprintf(stderr, "rump_sp: connect hook failed\n");
+ fprintf(stderr, "rump_sp: failed to read banner\n");
errno = error;
return -1;
}
- clispc.spc_fd = s;
- TAILQ_INIT(&clispc.spc_respwait);
- pthread_mutex_init(&clispc.spc_mtx, NULL);
- pthread_cond_init(&clispc.spc_cv, NULL);
-
- if ((n = read(s, banner, sizeof(banner)-1)) < 0) {
- fprintf(stderr, "rump_sp: failed to read banner\n");
- return -1;
- }
if (banner[n-1] != '\n') {
fprintf(stderr, "rump_sp: invalid banner\n");
@@ -260,5 +281,23 @@
/* parse the banner some day */
- return 0;
+ if ((error = parsetab[idx].connhook(s)) != 0) {
+ error = errno;
+ fprintf(stderr, "rump_sp: connect hook failed\n");
+ errno = error;
+ return -1;
+ }
+
+ pthread_mutex_init(&clispc.spc_mtx, NULL);
+ pthread_cond_init(&clispc.spc_cv, NULL);
+ clispc.spc_fd = s;
+ TAILQ_INIT(&clispc.spc_respwait);
+
+ error = handshake_req(&clispc);
+ if (error) {
+ pthread_mutex_destroy(&clispc.spc_mtx);
+ pthread_cond_destroy(&clispc.spc_cv);
+ close(s);
+ }
+ return error;
}
diff -r 112059144b1e -r 45f58de3cdcb lib/librumpuser/rumpuser_sp.c
--- a/lib/librumpuser/rumpuser_sp.c Thu Dec 16 16:59:05 2010 +0000
+++ b/lib/librumpuser/rumpuser_sp.c Thu Dec 16 17:05:44 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpuser_sp.c,v 1.26 2010/12/16 12:38:20 pooka Exp $ */
+/* $NetBSD: rumpuser_sp.c,v 1.27 2010/12/16 17:05:44 pooka Exp $ */
/*
* Copyright (c) 2010 Antti Kantee. All Rights Reserved.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: rumpuser_sp.c,v 1.26 2010/12/16 12:38:20 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_sp.c,v 1.27 2010/12/16 17:05:44 pooka Exp $");
#include <sys/types.h>
#include <sys/atomic.h>
@@ -198,6 +198,26 @@
}
static int
+send_handshake_resp(struct spclient *spc, uint64_t reqno, int error)
+{
+ struct rsp_hdr rhdr;
+ int rv;
+
+ rhdr.rsp_len = sizeof(rhdr) + sizeof(error);
+ rhdr.rsp_reqno = reqno;
+ rhdr.rsp_class = RUMPSP_RESP;
+ rhdr.rsp_type = RUMPSP_HANDSHAKE;
+ rhdr.rsp_error = 0;
+
+ sendlock(spc);
+ rv = dosend(spc, &rhdr, sizeof(rhdr));
+ rv = dosend(spc, &error, sizeof(error));
+ sendunlock(spc);
+
+ return rv;
+}
+
+static int
send_syscall_resp(struct spclient *spc, uint64_t reqno, int error,
register_t *retval)
{
@@ -355,7 +375,7 @@
close(spc->spc_fd);
spc->spc_fd = -1;
- spc->spc_dying = 0;
+ spc->spc_state = SPCSTATE_NEW;
atomic_inc_uint(&disco);
}
@@ -370,7 +390,7 @@
pfdlist[idx].fd = -1;
pfdlist[idx].revents = 0;
pthread_mutex_lock(&spc->spc_mtx);
- spc->spc_dying = 1;
+ spc->spc_state = SPCSTATE_DYING;
kickall(spc);
pthread_mutex_unlock(&spc->spc_mtx);
@@ -439,7 +459,7 @@
/* find empty slot the simple way */
for (i = 0; i < MAXCLI; i++) {
- if (pfdlist[i].fd == -1 && spclist[i].spc_dying == 0)
+ if (pfdlist[i].fd == -1 && spclist[i].spc_state == SPCSTATE_NEW)
break;
}
@@ -647,7 +667,24 @@
{
struct sysbouncearg *sba;
pthread_t pt;
- int retries;
+ int retries, rv;
+
+ if (__predict_false(spc->spc_state == SPCSTATE_NEW)) {
+ if (spc->spc_hdr.rsp_type != RUMPSP_HANDSHAKE) {
+ send_error_resp(spc, spc->spc_hdr.rsp_reqno, EAUTH);
+ spcfreebuf(spc);
+ return;
+ }
+
+ rv = send_handshake_resp(spc, spc->spc_hdr.rsp_reqno, 0);
+ spcfreebuf(spc);
+ if (rv) {
+ shutdown(spc->spc_fd, SHUT_RDWR);
+ return;
+ }
+ spc->spc_state = SPCSTATE_RUNNING;
+ return;
+ }
if (__predict_false(spc->spc_hdr.rsp_type != RUMPSP_SYSCALL)) {
send_error_resp(spc, spc->spc_hdr.rsp_reqno, EINVAL);
diff -r 112059144b1e -r 45f58de3cdcb lib/librumpuser/sp_common.c
--- a/lib/librumpuser/sp_common.c Thu Dec 16 16:59:05 2010 +0000
+++ b/lib/librumpuser/sp_common.c Thu Dec 16 17:05:44 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sp_common.c,v 1.16 2010/12/16 12:38:20 pooka Exp $ */
+/* $NetBSD: sp_common.c,v 1.17 2010/12/16 17:05:44 pooka Exp $ */
/*
* Copyright (c) 2010 Antti Kantee. All Rights Reserved.
@@ -76,11 +76,14 @@
*/
enum { RUMPSP_REQ, RUMPSP_RESP, RUMPSP_ERROR };
-enum { RUMPSP_SYSCALL,
+enum { RUMPSP_HANDSHAKE,
+ RUMPSP_SYSCALL,
RUMPSP_COPYIN, RUMPSP_COPYINSTR,
RUMPSP_COPYOUT, RUMPSP_COPYOUTSTR,
RUMPSP_ANONMMAP };
+enum { HANDSHAKE_GUEST, HANDSHAKE_AUTH }; /* more to come */
+
struct rsp_hdr {
uint64_t rsp_len;
uint64_t rsp_reqno;
@@ -93,11 +96,13 @@
union {
uint32_t sysnum;
uint32_t error;
+ uint32_t handshake;
} u;
};
#define HDRSZ sizeof(struct rsp_hdr)
#define rsp_sysnum u.sysnum
#define rsp_error u.error
+#define rsp_handshake u.handshake
#define MAXBANNER 96
@@ -132,7 +137,7 @@
struct spclient {
int spc_fd;
int spc_refcnt;
- int spc_dying;
+ int spc_state;
pthread_mutex_t spc_mtx;
pthread_cond_t spc_cv;
@@ -157,6 +162,10 @@
#define SPCSTATUS_BUSY 1
#define SPCSTATUS_WANTED 2
+#define SPCSTATE_NEW 0
+#define SPCSTATE_RUNNING 1
+#define SPCSTATE_DYING 2
+
typedef int (*addrparse_fn)(const char *, struct sockaddr **, int);
typedef int (*connecthook_fn)(int);
typedef void (*cleanup_fn)(struct sockaddr *);
@@ -334,7 +343,8 @@
sendunlockl(spc);
rw->rw_error = 0;
- while (rw->rw_data == NULL && rw->rw_error == 0 && spc->spc_dying == 0){
+ while (rw->rw_data == NULL && rw->rw_error == 0
+ && spc->spc_state != SPCSTATE_DYING){
/* are we free to receive? */
if (spc->spc_istatus == SPCSTATUS_FREE) {
int gotresp;
@@ -352,7 +362,7 @@
continue;
case -1:
rv = errno;
- spc->spc_dying = 1;
+ spc->spc_state = SPCSTATE_DYING;
goto cleanup;
default:
break;
@@ -391,7 +401,7 @@
if (rv)
return rv;
- if (spc->spc_dying)
+ if (spc->spc_state == SPCSTATE_DYING)
return ENOTCONN;
return rw->rw_error;
}
Home |
Main Index |
Thread Index |
Old Index