Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ## the C code for running lua as the callback language for Utu
- #include "hub.h"
- #include <lua.h>
- #include <lualib.h>
- #include <lauxlib.h>
- lua_State *L = NULL;
- const char *callback_names[] = {
- "start", "client_connect", "confirm_key", "peer_established",
- "member_registered", "member_failed", "peer_failed",
- "msg_recv", "msg_sent", "member_close", "error", "destroyed",
- "gen_key_start", "gen_key_done", "listening", "done"
- };
- int event_cb(UtuHub *hub, UtuHubEvent ev, void *data)
- {
- int lerr = 0;
- int on_stack = 0, top = 0;
- bstring key;
- CryptState *state = NULL;
- MyriadClient *client = NULL;
- assert(ev >= UEv_START && ev <= UEv_DONE && "event not within possible value range");
- top = lua_gettop(L);
- lua_getfield(L, LUA_GLOBALSINDEX, "Hub");
- lua_getfield(L, -1, callback_names[ev]);
- lua_replace(L, -3); // takes the callback and puts it before the hub so hub is self
- on_stack++;
- // some of the callbacks we just want to simplify rather than making
- // lua handle tons of data it doesn't need
- switch(ev) {
- case UEv_START:
- // register the hub for later
- lua_pushstring(L, "utu_hub");
- lua_pushlightuserdata(L, (void *)hub);
- /* registry["utu_hub"] = hub */
- lua_settable(L, LUA_REGISTRYINDEX);
- break;
- case UEv_CONFIRM_KEY:
- // push the identity and pubkey onto the stack as parameters
- state = (CryptState *)data;
- key = CryptState_export_key(state, CRYPT_THEIR_KEY, PK_PUBLIC);
- lua_pushlstring(L, (const char *)bdata(key), blength(key));
- on_stack++;
- bdestroy(key);
- break;
- case UEv_CLIENT_CONNECT: // fallthrough
- case UEv_PEER_FAILED:
- client = (MyriadClient *)data;
- struct sockaddr_in addr;
- unsigned int ip = 0;
- size_t addrlen = sizeof(addr);
- if (getpeername(client->fd, (struct sockaddr *)&addr, &addrlen) < 0){
- perror("getpeername");
- } else {
- ip = ntohl(addr.sin_addr.s_addr);
- }
- lua_pushinteger(L, ip);
- on_stack++;
- break;
- case UEv_GEN_KEY_DONE:
- // push the key bstring onto the stack
- key = (bstring)data;
- lua_pushlstring(L, (const char *)bdata(key), blength(key));
- on_stack++;
- break;
- default:
- if(data) {
- lua_pushlightuserdata(L, data);
- on_stack++;
- }
- }
- // do the function call and abort this client if there's an error
- if((lerr = lua_pcall(L, on_stack, 1, 0)) != 0) {
- log(ERROR, "calling %s lua function: %s", callback_names[ev], luaL_optstring (L, -1, "unknown error"));
- return 0;
- }
- // get the boolean off and return it
- lerr = lua_toboolean(L, -1);
- lua_pop(L, top);
- return lerr;
- }
- void setup_lua(const char *server) {
- int rc = 0;
- L = luaL_newstate();
- assert_mem(L);
- // open all the standard libraries
- luaL_openlibs(L);
- // load our little server script
- rc = luaL_loadfile(L, server);
- if(rc == 0) {
- // loading the file worked
- rc = lua_pcall(L, 0, LUA_MULTRET, 0);
- if(rc == 0) return; // good
- }
- // oops, an error fell through
- switch(rc) {
- case LUA_ERRRUN:
- log(ERROR, "lua error: %s", luaL_optstring (L, -1, "unknown error")); break;
- case LUA_ERRMEM: log(ERROR, "lua memory error"); break;
- case LUA_ERRERR: log(ERROR, "lua error while running error handler"); break;
- case LUA_ERRSYNTAX:
- log(ERROR, "syntax error: %s", luaL_optstring (L, -1, "unknown error"));
- break;
- case LUA_ERRFILE: log(ERROR, "couldn't load the file: %s", server); break;
- default: log(ERROR, "unknown lua error: %d", rc);
- }
- exit(1);
- }
- int main ( int argc, char *argv[] )
- {
- bstring host, port, name;
- if(argc != 4) {
- log(FAIL, "usage: server host port name");
- return 1;
- }
- host = bfromcstr(argv[1]);
- port = bfromcstr(argv[2]);
- name = bfromcstr(argv[3]);
- UtuHub_init(argv[0]);
- setup_lua("server.lua");
- UtuHub *hub = UtuHub_create_receiver(host, port, name, NULL, event_cb);
- UtuHub_start(hub);
- gc_shutdown();
- lua_close(L);
- return 0;
- }
- ## the simple Lua script that does the work
- -- functions needed:
- -- UtuHub
- -- UtuMsg
- -- UtuPeer
- -- Member
- function hex(digest)
- local dgst = {digest:byte(1,#digest)}
- local val = ""
- for i = 1, #dgst do
- val = val .. string.format("%02x:", dgst[i])
- end
- return val
- end
- Hub = { }
- function Hub:confirm_key(key)
- print("confim_key", hex(key))
- return true
- end
- function Hub:msg_sent(msg)
- print("msg_sent")
- return true
- end
- function Hub:client_connect(addr)
- print("client_connect", addr)
- return true
- end
- function Hub:peer_failed(addr)
- print("peer_failed", addr)
- return true
- end
- function Hub:peer_established(peer)
- print("peer_established")
- return true
- end
- function Hub:member_failed(peer)
- print("member_failed")
- return true
- end
- function Hub:member_registered(member)
- print("member_registered")
- return true
- end
- function Hub:msg_recv(msg)
- print("msg_recv")
- return true
- end
- function Hub:member_close(member)
- print("member_close")
- return true
- end
- function Hub:gen_key_start()
- print("gen_key_start")
- return true
- end
- function Hub:gen_key_done(key)
- print("gen_key_done", hex(key))
- return true
- end
- function Hub:start()
- print("start")
- return true
- end
- function Hub:listening()
- print("listening")
- return true
- end
- function Hub:done()
- print("done")
- return true
- end
- function Hub:destroyed()
- print("destroyed")
- return true
- end
Add Comment
Please, Sign In to add comment