summaryrefslogtreecommitdiff
path: root/accel-pptpd/triton
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-09-08 15:51:29 +0400
committerKozlov Dmitry <dima@server>2010-09-08 15:51:29 +0400
commit4c6469a9fd820db713251a645ac2499782f796ed (patch)
treefd7c4926eb2a3e2aa047bd14da429f3d6a5f8e6f /accel-pptpd/triton
parentec759f72fcf7d517fdfe8d043c75d0218363bc78 (diff)
downloadaccel-ppp-4c6469a9fd820db713251a645ac2499782f796ed.tar.gz
accel-ppp-4c6469a9fd820db713251a645ac2499782f796ed.zip
radius: implemented packet exchange
radius: implemented PAP authorization radius: implemented IP assigning triton: implemented userspace context switching and other stuff
Diffstat (limited to 'accel-pptpd/triton')
-rw-r--r--accel-pptpd/triton/md.c6
-rw-r--r--accel-pptpd/triton/timer.c6
-rw-r--r--accel-pptpd/triton/triton.c172
-rw-r--r--accel-pptpd/triton/triton.h17
-rw-r--r--accel-pptpd/triton/triton_p.h27
5 files changed, 151 insertions, 77 deletions
diff --git a/accel-pptpd/triton/md.c b/accel-pptpd/triton/md.c
index 3cb47a6..05d814c 100644
--- a/accel-pptpd/triton/md.c
+++ b/accel-pptpd/triton/md.c
@@ -86,16 +86,16 @@ static void *md_thread(void *arg)
return NULL;
}
-void __export triton_md_register_handler(struct triton_ctx_t *ctx, struct triton_md_handler_t *ud)
+void __export triton_md_register_handler(struct triton_context_t *ctx, struct triton_md_handler_t *ud)
{
struct _triton_md_handler_t *h = mempool_alloc(md_pool);
memset(h, 0, sizeof(*h));
h->ud = ud;
h->epoll_event.data.ptr = h;
if (ctx)
- h->ctx = (struct _triton_ctx_t *)ctx->tpd;
+ h->ctx = (struct _triton_context_t *)ctx->tpd;
else
- h->ctx = (struct _triton_ctx_t *)default_ctx->tpd;
+ h->ctx = (struct _triton_context_t *)default_ctx->tpd;
ud->tpd = h;
spin_lock(&h->ctx->lock);
list_add_tail(&h->entry, &h->ctx->handlers);
diff --git a/accel-pptpd/triton/timer.c b/accel-pptpd/triton/timer.c
index f34c19d..e9fd66a 100644
--- a/accel-pptpd/triton/timer.c
+++ b/accel-pptpd/triton/timer.c
@@ -86,7 +86,7 @@ void *timer_thread(void *arg)
return NULL;
}
-int __export triton_timer_add(struct triton_ctx_t *ctx, struct triton_timer_t *ud, int abs_time)
+int __export triton_timer_add(struct triton_context_t *ctx, struct triton_timer_t *ud, int abs_time)
{
struct _triton_timer_t *t = mempool_alloc(timer_pool);
@@ -95,9 +95,9 @@ int __export triton_timer_add(struct triton_ctx_t *ctx, struct triton_timer_t *u
t->epoll_event.data.ptr = t;
t->epoll_event.events = EPOLLIN | EPOLLET;
if (ctx)
- t->ctx = (struct _triton_ctx_t *)ctx->tpd;
+ t->ctx = (struct _triton_context_t *)ctx->tpd;
else
- t->ctx = (struct _triton_ctx_t *)default_ctx->tpd;
+ t->ctx = (struct _triton_context_t *)default_ctx->tpd;
t->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
if (t->fd < 0) {
triton_log_error("timer:timerfd_create: %s" ,strerror(errno));
diff --git a/accel-pptpd/triton/triton.c b/accel-pptpd/triton/triton.c
index 9aa7462..ba08c12 100644
--- a/accel-pptpd/triton/triton.c
+++ b/accel-pptpd/triton/triton.c
@@ -7,7 +7,7 @@
#include "triton_p.h"
-int thread_count = 4;
+int thread_count = 1;
int max_events = 64;
static spinlock_t threads_lock = SPINLOCK_INITIALIZER;
@@ -19,7 +19,7 @@ static LIST_HEAD(ctx_queue);
static spinlock_t ctx_list_lock = SPINLOCK_INITIALIZER;
static LIST_HEAD(ctx_list);
-struct triton_ctx_t *default_ctx;
+struct triton_context_t *default_ctx;
static int terminate;
static mempool_t *ctx_pool;
@@ -31,61 +31,25 @@ void triton_thread_wakeup(struct _triton_thread_t *thread)
static void* triton_thread(struct _triton_thread_t *thread)
{
- struct _triton_md_handler_t *h;
- struct _triton_timer_t *t;
sigset_t set;
int sig;
- uint64_t tt;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigaddset(&set, SIGQUIT);
- while(1){
+ while (1) {
sigwait(&set, &sig);
cont:
- if (thread->ctx->need_close) {
- if (thread->ctx->ud->close)
- thread->ctx->ud->close(thread->ctx->ud);
- thread->ctx->need_close = 0;
- }
-
- while (1) {
- spin_lock(&thread->ctx->lock);
- if (!list_empty(&thread->ctx->pending_timers)) {
- t = list_entry(thread->ctx->pending_timers.next, typeof(*t), entry2);
- list_del(&t->entry2);
- t->pending = 0;
- spin_unlock(&thread->ctx->lock);
- read(t->fd, &tt, sizeof(tt));
- t->ud->expire(t->ud);
- }
- if (!list_empty(&thread->ctx->pending_handlers)) {
- h = list_entry(thread->ctx->pending_handlers.next, typeof(*h), entry2);
- list_del(&h->entry2);
- h->pending = 0;
- spin_unlock(&thread->ctx->lock);
-
- if (h->trig_epoll_events & (EPOLLIN | EPOLLERR | EPOLLHUP))
- if (h->ud->read)
- if (h->ud->read(h->ud))
- continue;
- if (h->trig_epoll_events & (EPOLLOUT | EPOLLERR | EPOLLHUP))
- if (h->ud->write)
- if (h->ud->write(h->ud))
- continue;
- h->trig_epoll_events = 0;
- continue;
- }
- thread->ctx->thread = NULL;
- spin_unlock(&thread->ctx->lock);
- if (thread->ctx->need_free)
- mempool_free(thread->ctx);
- thread->ctx = NULL;
- break;
+ if (swapcontext(&thread->uctx, &thread->ctx->uctx)) {
+ triton_log_error("swapcontext: %s\n", strerror(errno));
}
+ if (thread->ctx->need_free)
+ mempool_free(thread->ctx);
+ thread->ctx = NULL;
+
spin_lock(&threads_lock);
if (!list_empty(&ctx_queue)) {
thread->ctx = list_entry(ctx_queue.next, typeof(*thread->ctx), entry2);
@@ -106,6 +70,55 @@ cont:
}
}
+static void ctx_thread(struct _triton_context_t *ctx)
+{
+ struct _triton_md_handler_t *h;
+ struct _triton_timer_t *t;
+ uint64_t tt;
+ ucontext_t *uctx;
+
+ while (1) {
+ uctx = &ctx->thread->uctx;
+ if (ctx->need_close) {
+ if (ctx->ud->close)
+ ctx->ud->close(ctx->ud);
+ ctx->need_close = 0;
+ }
+
+ while (1) {
+ spin_lock(&ctx->lock);
+ if (!list_empty(&ctx->pending_timers)) {
+ t = list_entry(ctx->pending_timers.next, typeof(*t), entry2);
+ list_del(&t->entry2);
+ t->pending = 0;
+ spin_unlock(&ctx->lock);
+ read(t->fd, &tt, sizeof(tt));
+ t->ud->expire(t->ud);
+ continue;
+ }
+ if (!list_empty(&ctx->pending_handlers)) {
+ h = list_entry(ctx->pending_handlers.next, typeof(*h), entry2);
+ list_del(&h->entry2);
+ h->pending = 0;
+ spin_unlock(&ctx->lock);
+ if (h->trig_epoll_events & (EPOLLIN | EPOLLERR | EPOLLHUP))
+ if (h->ud && h->ud->read)
+ h->ud->read(h->ud);
+ if (h->trig_epoll_events & (EPOLLOUT | EPOLLERR | EPOLLHUP))
+ if (h->ud && h->ud->write)
+ h->ud->write(h->ud);
+ h->trig_epoll_events = 0;
+ continue;
+ }
+ ctx->thread = NULL;
+ spin_unlock(&ctx->lock);
+
+ if (swapcontext(&ctx->uctx, uctx))
+ triton_log_error("swapcontext: %s\n", strerror(errno));
+ }
+ }
+}
+
struct _triton_thread_t *create_thread()
{
struct _triton_thread_t *thread = malloc(sizeof(*thread));
@@ -121,9 +134,9 @@ struct _triton_thread_t *create_thread()
return thread;
}
-int triton_queue_ctx(struct _triton_ctx_t *ctx)
+int triton_queue_ctx(struct _triton_context_t *ctx)
{
- if (ctx->thread || ctx->queued)
+ if (ctx->thread || ctx->queued || ctx->sleeping)
return 0;
spin_lock(&threads_lock);
@@ -142,9 +155,9 @@ int triton_queue_ctx(struct _triton_ctx_t *ctx)
return 1;
}
-void __export triton_register_ctx(struct triton_ctx_t *ud)
+int __export triton_context_register(struct triton_context_t *ud)
{
- struct _triton_ctx_t *ctx = mempool_alloc(ctx_pool);
+ struct _triton_context_t *ctx = mempool_alloc(ctx_pool);
memset(ctx, 0, sizeof(*ctx));
ctx->ud = ud;
@@ -154,16 +167,33 @@ void __export triton_register_ctx(struct triton_ctx_t *ud)
INIT_LIST_HEAD(&ctx->pending_handlers);
INIT_LIST_HEAD(&ctx->pending_timers);
+ if (getcontext(&ctx->uctx)) {
+ triton_log_error("getcontext: %s\n", strerror(errno));
+ free(ctx);
+ return -1;
+ }
+
+ ctx->uctx.uc_stack.ss_size = CTX_STACK_SIZE;
+ ctx->uctx.uc_stack.ss_sp = malloc(CTX_STACK_SIZE);
+ if (!ctx->uctx.uc_stack.ss_sp) {
+ triton_log_error("out of memory\n");
+ free(ctx);
+ return -1;
+ }
+ makecontext(&ctx->uctx, (void (*)())ctx_thread, 1, ctx);
+
ud->tpd = ctx;
spin_lock(&ctx_list_lock);
list_add_tail(&ctx->entry, &ctx_list);
spin_unlock(&ctx_list_lock);
+
+ return 0;
}
-void __export triton_unregister_ctx(struct triton_ctx_t *ud)
+void __export triton_context_unregister(struct triton_context_t *ud)
{
- struct _triton_ctx_t *ctx = (struct _triton_ctx_t *)ud->tpd;
+ struct _triton_context_t *ctx = (struct _triton_context_t *)ud->tpd;
if (!list_empty(&ctx->handlers)) {
triton_log_error("BUG:ctx:triton_unregister_ctx: handlers is not empty");
@@ -175,6 +205,14 @@ void __export triton_unregister_ctx(struct triton_ctx_t *ud)
}
if (!list_empty(&ctx->timers)) {
triton_log_error("BUG:ctx:triton_unregister_ctx: timers is not empty");
+ {
+ struct _triton_timer_t *t;
+ while(!list_empty(&ctx->timers)) {
+ t = list_entry(ctx->timers.next, typeof(*t), entry);
+ t->ud->expire(t->ud);
+ list_del(&t->entry);
+ }
+ }
abort();
}
if (!list_empty(&ctx->pending_timers)) {
@@ -187,17 +225,43 @@ void __export triton_unregister_ctx(struct triton_ctx_t *ud)
list_del(&ctx->entry);
spin_unlock(&ctx_list_lock);
}
+void __export triton_context_schedule(struct triton_context_t *ud)
+{
+ struct _triton_context_t *ctx = (struct _triton_context_t *)ud->tpd;
+ ucontext_t *uctx = &ctx->thread->uctx;
+
+ spin_lock(&ctx->lock);
+ ctx->sleeping = 1;
+ ctx->thread = NULL;
+ spin_unlock(&ctx->lock);
+
+ if (swapcontext(&ctx->uctx, uctx))
+ triton_log_error("swaswpntext: %s\n", strerror(errno));
+}
+
+void __export triton_context_wakeup(struct triton_context_t *ud)
+{
+ struct _triton_context_t *ctx = (struct _triton_context_t *)ud->tpd;
+ int r;
+
+ spin_lock(&ctx->lock);
+ ctx->sleeping = 0;
+ r = triton_queue_ctx(ctx);
+ spin_unlock(&ctx->lock);
+ if (r)
+ triton_thread_wakeup(ctx->thread);
+}
int __export triton_init(const char *conf_file, const char *mod_sect)
{
- ctx_pool = mempool_create(sizeof(struct _triton_ctx_t));
+ ctx_pool = mempool_create(sizeof(struct _triton_context_t));
default_ctx = malloc(sizeof(*default_ctx));
if (!default_ctx) {
fprintf(stderr,"cann't allocate memory\n");
return -1;
}
- triton_register_ctx(default_ctx);
+ triton_context_register(default_ctx);
if (conf_load(conf_file))
return -1;
@@ -237,7 +301,7 @@ void __export triton_run()
void __export triton_terminate()
{
- struct _triton_ctx_t *ctx;
+ struct _triton_context_t *ctx;
struct _triton_thread_t *t;
md_terminate();
diff --git a/accel-pptpd/triton/triton.h b/accel-pptpd/triton/triton.h
index 2cc5ccf..735264a 100644
--- a/accel-pptpd/triton/triton.h
+++ b/accel-pptpd/triton/triton.h
@@ -5,11 +5,11 @@
#include "list.h"
-struct triton_ctx_t
+struct triton_context_t
{
const void *tpd; // triton private data, don't touch!
- void (*close)(struct triton_ctx_t*);
- void (*free)(struct triton_ctx_t*);
+ void (*close)(struct triton_context_t*);
+ void (*free)(struct triton_context_t*);
};
struct triton_md_handler_t
@@ -41,18 +41,19 @@ struct conf_sect_t
struct list_head items;
};
-void triton_register_ctx(struct triton_ctx_t *);
-void triton_unregister_ctx(struct triton_ctx_t *);
-void triton_ctx_schedule(struct triton_md_handler_t *, struct triton_timer_t *);
+int triton_context_register(struct triton_context_t *);
+void triton_context_unregister(struct triton_context_t *);
+void triton_context_schedule(struct triton_context_t *);
+void triton_context_wakeup(struct triton_context_t *);
#define MD_MODE_READ 1
#define MD_MODE_WRITE 2
-void triton_md_register_handler(struct triton_ctx_t *, struct triton_md_handler_t *);
+void triton_md_register_handler(struct triton_context_t *, struct triton_md_handler_t *);
void triton_md_unregister_handler(struct triton_md_handler_t *h);
int triton_md_enable_handler(struct triton_md_handler_t *h, int mode);
int triton_md_disable_handler(struct triton_md_handler_t *h,int mode);
-int triton_timer_add(struct triton_ctx_t *ctx, struct triton_timer_t*,int abs_time);
+int triton_timer_add(struct triton_context_t *ctx, struct triton_timer_t*,int abs_time);
int triton_timer_mod(struct triton_timer_t *,int abs_time);
void triton_timer_del(struct triton_timer_t *);
diff --git a/accel-pptpd/triton/triton_p.h b/accel-pptpd/triton/triton_p.h
index c31efd6..0aa37b1 100644
--- a/accel-pptpd/triton/triton_p.h
+++ b/accel-pptpd/triton/triton_p.h
@@ -3,43 +3,52 @@
#include <pthread.h>
#include <sys/epoll.h>
+#include <ucontext.h>
#include "triton.h"
#include "list.h"
#include "spinlock.h"
+#define CTX_STACK_SIZE 8196
+
struct _triton_thread_t
{
struct list_head entry;
struct list_head entry2;
pthread_t thread;
int terminate:1;
- struct _triton_ctx_t *ctx;
+ struct _triton_context_t *ctx;
+ ucontext_t uctx;
};
-struct _triton_ctx_t
+struct _triton_context_t
{
struct list_head entry;
struct list_head entry2;
+
spinlock_t lock;
+ struct _triton_thread_t *thread;
+
struct list_head handlers;
struct list_head timers;
-
- struct _triton_thread_t *thread;
struct list_head pending_handlers;
struct list_head pending_timers;
+
+ ucontext_t uctx;
+
int queued:1;
+ int sleeping:1;
int need_close:1;
int need_free:1;
- struct triton_ctx_t *ud;
+ struct triton_context_t *ud;
};
struct _triton_md_handler_t
{
struct list_head entry;
struct list_head entry2;
- struct _triton_ctx_t *ctx;
+ struct _triton_context_t *ctx;
struct epoll_event epoll_event;
uint32_t trig_epoll_events;
int pending:1;
@@ -51,7 +60,7 @@ struct _triton_timer_t
struct list_head entry;
struct list_head entry2;
struct epoll_event epoll_event;
- struct _triton_ctx_t *ctx;
+ struct _triton_context_t *ctx;
int fd;
int pending:1;
struct triton_timer_t *ud;
@@ -76,8 +85,8 @@ void md_run();
void md_terminate();
void timer_run();
void timer_terminate();
-struct triton_ctx_t *default_ctx;
-int triton_queue_ctx(struct _triton_ctx_t*);
+struct triton_context_t *default_ctx;
+int triton_queue_ctx(struct _triton_context_t*);
void triton_thread_wakeup(struct _triton_thread_t*);
int conf_load(const char *fname);
void triton_log_error(const char *fmt,...);