<commit_before>/* 
 * Lua stub to link lua to ldns
 *
 * This also exports functions for lua use
 * partely based upon:
 * http://tonyandpaige.com/tutorials/lua3.html
 *
 * (c) <NAME>, NLnet Labs
 */

/****
 * BIG TODO error handling and checking from the lua 
 * side
 *
 * Can't use doxygen, because everything goes through
 * lua_State's stack
 */

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <stdbool.h>

#include <stdint.h>

/* lua includes */
#include <lua50/lua.h>
#include <lua50/lualib.h>
#include <lua50/lauxlib.h>

/* ldns include */
#include <ldns/dns.h>

/* the Lua interpreter */
lua_State* L;

char *VERSION = "lua-rns 0.1";

void
usage(FILE *f, char *progname)
{
	fprintf(f, "Synopsis: %s lua-script\n", progname);
	fprintf(f, "   No options are defined (yet)\n");
}

void
version(FILE *f, char *progname)
{
	fprintf(f, "%s version %s\n", progname, VERSION);
}

/*
=====================================================
 Lua bindings for ldns
=====================================================
*/


/*
==========
 RDF
==========
 */
l_rdf_new_frm_str(lua_State *L)
{
	uint16_t t = (uint16_t)lua_tonumber(L, 1);
	char *str = strdup((char*)luaL_checkstring(L, 2));

	ldns_rdf *new_rdf = ldns_rdf_new_frm_str((ldns_rdf_type)t, str);

	if (new_rdf) {
		lua_pushlightuserdata(L, new_rdf);
		return 1;
	} else {
		return 0;
	}
}

static int
l_rdf_print(lua_State *L)
{
	/* we always print to stdout */
	ldns_rdf *toprint = (ldns_rdf*)lua_touserdata(L, 1); /* pop from the stack */
	ldns_rdf_print(stdout, toprint);
	return 0;
}

static int
l_rdf_free(lua_State *L)
{
	ldns_rdf *tofree = (ldns_rdf*)lua_touserdata(L, 1); /* pop from the stack */
	ldns_rdf_free(tofree);
	return 0;
}


/*
==========
 RR 
==========
*/
static int
l_rr_new_frm_str(lua_State *L)
{
	/* pop string from stack, make new rr, push rr to
	 * stack and return 1 - to signal the new pointer
	 */
	char *str = strdup((char*)luaL_checkstring(L, 1));
	uint16_t ttl = (uint16_t)lua_tonumber(L, 2);
	ldns_rdf *orig = (ldns_rdf*)lua_touserdata(L, 2);
	
	ldns_rr *new_rr = ldns_rr_new_frm_str(str, ttl, orig);

	if (new_rr) {
		lua_pushlightuserdata(L, new_rr);
		return 1;
	} else {
		return 0;
	}
}

static int
l_rr_print(lua_State *L)
{
	/* we always print to stdout */
	ldns_rr *toprint = (ldns_rr*)lua_touserdata(L, 1); /* pop from the stack */
	ldns_rr_print(stdout, toprint);
	return 0;
}

static int
l_rr_free(lua_State *L)
{
	ldns_rr *tofree = (ldns_rr*)lua_touserdata(L, 1); /* pop from the stack */
	ldns_rr_free(tofree);
	return 0;
}

/*
=========
 PACKETS
=========
*/
static int
l_pkt_new(lua_State *L)
{
	ldns_pkt *new_pkt = ldns_pkt_new();
	if (new_pkt) {
		lua_pushlightuserdata(L, new_pkt);
		return 1;
	} else {
		return 0;
	}
}


static int
l_pkt_push_rr(lua_State *L)
{
	ldns_pkt *pkt = (ldns_pkt*)lua_touserdata(L, 1); /* get the packet */
	ldns_pkt_section s = (ldns_pkt_section)lua_tonumber(L, 2); /* the section where to put it */
	ldns_rr *rr = (ldns_rr*)lua_touserdata(L, 3); /* the rr to put */

	if (ldns_pkt_push_rr(pkt, s, rr)) {
		lua_pushlightuserdata(L, pkt);
		return 1;
	} else {
		return 0;
	}
}

static int
l_pkt_insert_rr(lua_State *L)
{
	ldns_pkt *p = (ldns_pkt*)lua_touserdata(L, 1);
	ldns_rr *rr = (ldns_rr*)lua_touserdata(L, 2);
	uint16_t n = (uint16_t)lua_tonumber(L, 3);

	if(ldns_pkt_insert_rr(p, rr, n)) {
		lua_pushlightuserdata(L, p);
		return 1;
	} else {
		return 0;
	}
}

static int
l_pkt_get_rr(lua_State *L)
{
	ldns_pkt *p = (ldns_pkt*)lua_touserdata(L, 1); /* pop from the stack */
	uint16_t n = (uint16_t) lua_tonumber(L, 2);
	ldns_rr *r;

	r = ldns_pkt_get_rr(p, n);
	if (r) {
		lua_pushlightuserdata(L, r);
		return 1;
	} else {
		return 0;
	}
}

static int
l_pkt_set_rr(lua_State *L)
{
	ldns_pkt *p = (ldns_pkt*)lua_touserdata(L, 1);
	ldns_rr *rr = (ldns_rr*)lua_touserdata(L, 2);
	uint16_t n = (uint16_t)lua_tonumber(L, 3);
	ldns_rr *r;

	r = ldns_pkt_set_rr(p, rr, n);
	if (r) {
		lua_pushlightuserdata(L, r);
		return 1;
	} else {
		return 0;
	}
}

static int
l_pkt_rr_count(lua_State *L)
{
	ldns_pkt *p = (ldns_pkt*)lua_touserdata(L, 1);
	lua_pushnumber(L, ldns_pkt_section_count(p, LDNS_SECTION_ANY));
	return 1;
}

static int
l_pkt_print(lua_State *L)
{
	/* we always print to stdout */
	ldns_pkt *toprint = (ldns_pkt*)lua_touserdata(L, 1); /* pop from the stack */
	ldns_pkt_print(stdout, toprint);
	return 0;
}

/*
===========
 NETWORKIBG
===========
 */

static int
l_server_socket_udp(lua_State *L)
{
	ldns_rdf *ip = (ldns_rdf*)lua_touserdata(L, 1); /* get the ip */
	uint16_t port = (uint16_t)lua_tonumber(L, 2); /* port number */
	struct timeval timeout;
	struct sockaddr_storage *to;
	size_t socklen;
	int sockfd;

	/* use default timeout - maybe this gets to be configureable */
	timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC;
	timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC;

	/* socklen isn't really usefull here */
	to = ldns_rdf2native_sockaddr_storage(ip, port, &socklen);
	if (!to) {
		return 0;
	}

	/* get the socket */
	sockfd = ldns_udp_server_connect(to, timeout);
	if (sockfd == 0) {
		return 0;
	}
	lua_pushnumber(L, (lua_Number)sockfd);
	return 1;
}

static int
l_client_socket_udp(lua_State *L)
{
	ldns_rdf *ip = (ldns_rdf*)lua_touserdata(L, 1); /* get the ip */
	uint16_t port = (uint16_t)lua_tonumber(L, 2); /* port number */
	struct timeval timeout;
	struct sockaddr_storage *to;
	size_t socklen;
	int sockfd;

	/* use default timeout - maybe this gets to be configureable */
	timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC;
	timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC;

	/* socklen isn't really usefull here */
	to = ldns_rdf2native_sockaddr_storage(ip, port, &socklen);
	if (!to) {
		return 0;
	}

	/* get the socket */
	sockfd = ldns_udp_connect(to, timeout);
	if (sockfd == 0) {
		return 0;
	}
	lua_pushnumber(L, (lua_Number)sockfd);
	return 1;
}

static int
l_server_socket_close_udp(lua_State *L)
{
	int sockfd = (int)lua_tonumber(L, 1);

	close(sockfd);
}

static int
l_write_wire_udp(lua_State *L)
{
	int sockfd = (int)lua_tonumber(L, 1);
	ldns_buffer *pktbuf = (ldns_buffer*)lua_touserdata(L, 2);
	ldns_rdf *rdf_to = (ldns_rdf*)lua_touserdata(L, 3);
	uint16_t port = (uint16_t)lua_tonumber(L, 4); /* port number */

	struct sockaddr_storage *to;
	size_t socklen;
	ssize_t bytes;
	
	/* port number is handled in the socket */
	to = ldns_rdf2native_sockaddr_storage(rdf_to, port, &socklen);<commit_msg>networking stuff is almost working from within lua<commit_after>/* 
 * Lua stub to link lua to ldns
 *
 * This also exports functions for lua use
 * partely based upon:
 * http://tonyandpaige.com/tutorials/lua3.html
 *
 * (c) <NAME>, NLnet Labs
 */

/****
 * BIG TODO error handling and checking from the lua 
 * side
 *
 * Can't use doxygen, because everything goes through
 * lua_State's stack
 */

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <stdbool.h>

#include <stdint.h>

/* lua includes */
#include <lua50/lua.h>
#include <lua50/lualib.h>
#include <lua50/lauxlib.h>

/* ldns include */
#include <ldns/dns.h>

/* the Lua interpreter */
lua_State* L;

char *VERSION = "lua-rns 0.1";

void
usage(FILE *f, char *progname)
{
	fprintf(f, "Synopsis: %s lua-script\n", progname);
	fprintf(f, "   No options are defined (yet)\n");
}

void
version(FILE *f, char *progname)
{
	fprintf(f, "%s version %s\n", progname, VERSION);
}

/*
=====================================================
 Lua bindings for ldns
=====================================================
*/


/*
==========
 RDF
==========
 */
l_rdf_new_frm_str(lua_State *L)
{
	uint16_t t = (uint16_t)lua_tonumber(L, 1);
	char *str = strdup((char*)luaL_checkstring(L, 2));

	ldns_rdf *new_rdf = ldns_rdf_new_frm_str((ldns_rdf_type)t, str);

	if (new_rdf) {
		lua_pushlightuserdata(L, new_rdf);
		return 1;
	} else {
		return 0;
	}
}

static int
l_rdf_print(lua_State *L)
{
	/* we always print to stdout */
	ldns_rdf *toprint = (ldns_rdf*)lua_touserdata(L, 1); /* pop from the stack */
	ldns_rdf_print(stdout, toprint);
	return 0;
}

static int
l_rdf_free(lua_State *L)
{
	ldns_rdf *tofree = (ldns_rdf*)lua_touserdata(L, 1); /* pop from the stack */
	ldns_rdf_free(tofree);
	return 0;
}


/*
==========
 RR 
==========
*/
static int
l_rr_new_frm_str(lua_State *L)
{
	/* pop string from stack, make new rr, push rr to
	 * stack and return 1 - to signal the new pointer
	 */
	char *str = strdup((char*)luaL_checkstring(L, 1));
	uint16_t ttl = (uint16_t)lua_tonumber(L, 2);
	ldns_rdf *orig = (ldns_rdf*)lua_touserdata(L, 2);
	
	ldns_rr *new_rr = ldns_rr_new_frm_str(str, ttl, orig);

	if (new_rr) {
		lua_pushlightuserdata(L, new_rr);
		return 1;
	} else {
		return 0;
	}
}

static int
l_rr_print(lua_State *L)
{
	/* we always print to stdout */
	ldns_rr *toprint = (ldns_rr*)lua_touserdata(L, 1); /* pop from the stack */
	ldns_rr_print(stdout, toprint);
	return 0;
}

static int
l_rr_free(lua_State *L)
{
	ldns_rr *tofree = (ldns_rr*)lua_touserdata(L, 1); /* pop from the stack */
	ldns_rr_free(tofree);
	return 0;
}

/*
=========
 PACKETS
=========
*/
static int
l_pkt_new(lua_State *L)
{
	ldns_pkt *new_pkt = ldns_pkt_new();
	if (new_pkt) {
		lua_pushlightuserdata(L, new_pkt);
		return 1;
	} else {
		return 0;
	}
}


static int
l_pkt_push_rr(lua_State *L)
{
	ldns_pkt *pkt = (ldns_pkt*)lua_touserdata(L, 1); /* get the packet */
	ldns_pkt_section s = (ldns_pkt_section)lua_tonumber(L, 2); /* the section where to put it */
	ldns_rr *rr = (ldns_rr*)lua_touserdata(L, 3); /* the rr to put */

	if (ldns_pkt_push_rr(pkt, s, rr)) {
		lua_pushlightuserdata(L, pkt);
		return 1;
	} else {
		return 0;
	}
}

static int
l_pkt_insert_rr(lua_State *L)
{
	ldns_pkt *p = (ldns_pkt*)lua_touserdata(L, 1);
	ldns_rr *rr = (ldns_rr*)lua_touserdata(L, 2);
	uint16_t n = (uint16_t)lua_tonumber(L, 3);

	if(ldns_pkt_insert_rr(p, rr, n)) {
		lua_pushlightuserdata(L, p);
		return 1;
	} else {
		return 0;
	}
}

static int
l_pkt_get_rr(lua_State *L)
{
	ldns_pkt *p = (ldns_pkt*)lua_touserdata(L, 1); /* pop from the stack */
	uint16_t n = (uint16_t) lua_tonumber(L, 2);
	ldns_rr *r;

	r = ldns_pkt_get_rr(p, n);
	if (r) {
		lua_pushlightuserdata(L, r);
		return 1;
	} else {
		return 0;
	}
}

static int
l_pkt_set_rr(lua_State *L)
{
	ldns_pkt *p = (ldns_pkt*)lua_touserdata(L, 1);
	ldns_rr *rr = (ldns_rr*)lua_touserdata(L, 2);
	uint16_t n = (uint16_t)lua_tonumber(L, 3);
	ldns_rr *r;

	r = ldns_pkt_set_rr(p, rr, n);
	if (r) {
		lua_pushlightuserdata(L, r);
		return 1;
	} else {
		return 0;
	}
}

static int
l_pkt_rr_count(lua_State *L)
{
	ldns_pkt *p = (ldns_pkt*)lua_touserdata(L, 1);
	if (!p) {
		return 0;
	}
	
	lua_pushnumber(L, ldns_pkt_section_count(p, LDNS_SECTION_ANY));
	return 1;
}

static int
l_pkt_print(lua_State *L)
{
	/* we always print to stdout */
	ldns_pkt *toprint = (ldns_pkt*)lua_touserdata(L, 1); /* pop from the stack */
	ldns_pkt_print(stdout, toprint);
	return 0;
}

/*
===========
 NETWORKIBG
===========
 */

static int
l_server_socket_udp(lua_State *L)
{
	ldns_rdf *ip = (ldns_rdf*)lua_touserdata(L, 1); /* get the ip */
	uint16_t port = (uint16_t)lua_tonumber(L, 2); /* port number */
	struct timeval timeout;
	struct sockaddr_storage *to;
	size_t socklen;
	int sockfd;

	/* use default timeout - maybe this gets to be configureable */
	timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC;
	timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC;

	/* socklen isn't really usefull here */
	to = ldns_rdf2native_sockaddr_storage(ip, port, &socklen);
	if (!to) {
		return 0;
	}

	/* get the socket */
	sockfd = ldns_udp_server_connect(to, timeout);
	if (sockfd == 0) {
		return 0;
	}
	lua_pushnumber(L, (lua_Number)sockfd);
	return 1;
}

static int
l_client_socket_udp(lua_State *L)
{
	ldns_rdf *ip = (ldns_rdf*)lua_touserdata(L, 1); /* get the ip */
	uint16_t port = (uint16_t)lua_tonumber(L, 2); /* port number */
	struct timeval timeout;
	struct sockaddr_storage *to;
	size_t socklen;
	int sockfd;

	if (!ip || port == 0) {
		return 0;
	}

	/* use default timeout - maybe this gets to be configureable */
	timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC;
	timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC;

	/* socklen isn't really usefull here */
	to = ldns_rdf2native_sockaddr_storage(ip, port, &socklen);
	if (!to) {
		return 0;
	}

	/* get the socket */
	sockfd = ldns_udp_connect(to, timeout);
	if (sockfd == 0) {
		return 0;
	}
	lua_pushnumber(L, (lua_Number)sockfd);
	return 1;
}

static int
l_server_socket_close_udp(lua_State *L)
{
	int sockfd = (int)lua_tonumber(L, 1);

	close(sockfd);
}

static int
l_write_wire_udp(lua_State *L)
{
	int sockfd = (int)lua_tonumber(L, 1);
	ldns_buffer *pktbuf = (ldns_buffer*)lua_touserdata(L, 2);
	ldns_rdf *rdf_to = (ldns_rdf*)lua_touserdata(L, 3);
	uint16_t port = (uint16_t)lua_tonumber(L, 4); /* port number */

	struct sockaddr_storage *to;
	size_t socklen;
	ssize_t bytes;

	if (!pktbuf || !rdf_to || port == 0) {
		return 0;
	}
	
	/* port number is handled in the socket */
	to = ldns_rdf2native_sockaddr_storage(rdf_to, port, &socklen);
{'fraction_non_alphanumeric': 0.16692343244492375, 'fraction_numerical': 0.01640733323062702, 'mean_word_length': 4.364876033057851, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1944626', 'n_tokens_mistral': 6020, 'n_tokens_neox': 5719, 'n_words': 1257}