Difference between revisions of "Peerd.c"

From Organic Design wiki
(define globals at start)
m
 
(174 intermediate revisions by 3 users not shown)
Line 1: Line 1:
// This article and all its includes are licenced under LGPL
+
{{legacy}}
// GPL: http://www.gnu.org/copyleft/lesser.html
+
<source lang="c">
// SRC: http://www.organicdesign.co.nz/server.c
+
// http://www.organicdesign.co.nz/peerd - nodal p2p wiki daemon
 +
// Source: http://www.organicdesign.co.nz/peerd/files/C - the C language version for *ix,OSX,NT platforms
 +
// This article and all its includes are licenced under http://www.gnu.org/copyleft/lesser.html
 +
// Compiled in Win32 by peerd.c/win32-makefile to http://www.organicdesign.co.nz/wiki/images/a/a2/Peerd.msi
 +
// Compiled in Linux and OSX by rp to peerd.deb and peerd.dmg
  
#define DELAY 1        // normal operation is 0 for no delay
+
// Globals
#define PAKSIZE 128    // keep packet-size small for non-multithreaded design
+
int this = 0,parent,grandpa,port = 80;
#define BUFSIZE 10000  // dictates max message size
+
char *peer = "default";
#define MAXCLIENTS 1000 // used by listen()
+
char *file = (char*)0;
  
// Set up structures for socket & select
+
// Reserved nodes used by nodal reduction process (tmp)
struct sockaddr_in addr;
+
#define nodeTRUE  1  // [[[[nodeTRUE]]]]
struct timeval to;
+
#define nodeNEXT  1  // [[[[nodeNEXT]]]]
fd_set *fdset;
+
#define nodePREV  2  // [[[[nodePREV]]]]
unsigned long int sockopt_on = 1;
+
#define nodeCODE  3  // [[[[nodeCODE]]]] is a [[[[association|pseudo node-value]]]] to determine is the nodes non-nodal-data is a function-ref
int sock, szAddr = sizeof(struct sockaddr_in);
+
#define nodePARENT 4  // [[[[nodePARENT]]]] updated by [[[[nodal reduction]]]], the node for which thsi is the [[[[focus]]]]
memset((char*)&addr, 0, szAddr); // zero the struct
+
#define nodeTRIE  5  // [[[[nodeTRIE]]]] use a different root for trie/hash so it can't interfere with serialisation of nodal-root
addr.sin_family = PF_INET;
+
#define nodeFIRST  6  // [[[[nodeFIRST]]]]
addr.sin_port = htons(port);
+
#define nodeLAST  7  // [[[[nodeLAST]]]]
addr.sin_addr.s_addr = htonl(INADDR_ANY);
+
#define nodeMAKE  8  // [[[[nodeMAKE]]]]
 +
#define nodeINIT  9  // [[[[nodeINIT]]]]
 +
#define nodeMAIN  10 // [[[[nodeMAIN]]]]
 +
#define nodeEXIT  11 // [[[[nodeEXIT]]]]
  
// struct for a stream-node's state to point to
 
typedef struct siStruct {
 
int fd, inptr, outptr;
 
char *inbuf, *outbuf;
 
} streamInfo;
 
  
// make the passed socket non-blocking so accept() returns straight away for multiplexed model
+
#include <unistd.h>
// - if no incoming requests, returns EAGAIN or EWOULDBLOCK state
+
#include <stdlib.h>
int nonblocking(int socket) {
+
#include <stdio.h>
#if __WIN32__
+
#include <string.h>
ioctlsocket(socket,FIONBIO,&sockopt_on);
+
#include <errno.h>
#else
+
#include <math.h>
fcntl(socket,F_SETFL,fcntl(socket,F_GETFL)|O_NONBLOCK);
+
#include <stdarg.h>
#endif
+
#include <time.h>
return socket;
+
#include <regex.h>
}
+
#include "util.h"           // [[[[util.c]]]]: General utils, file,log,string etc
 
 
// Do the usual socket polava: create,options,bind,listen
 
err = 0;
 
if ((sock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0) logErr("socket() failed!");
 
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char*)&sockopt_on,sizeof(int))<0) logErr("setsockopt() failed!");
 
if (bind(nonblocking(sock),(struct sockaddr*)&addr,szAddr)<0) logErr("bind() failed!");
 
if (listen(sock,MAXCLIENTS)<0) logErr("listen() failed!");
 
if (err) logAdd("Server failed to start!");
 
 
 
// Parses a message content and responds to client
 
void processMessage(char* msg) {
 
 
 
// Create a new context node
 
 
 
// validate and extract event, params and mime-type
 
//    /GET\s+\/+(.*?)(\/(.+))?\s+(HTTP\/[0-9.]+)/
 
 
 
// add appropriate response to nodal context
 
// - restart, click?x&y, else content/mime/type
 
 
 
}
 
 
 
 
 
// Function called by each stream-node in network's reduction loop
 
// - there is also a streams-container node containing zero or more stream nodes
 
void server() {
 
FD_ZERO(fdset);
 
FD_SET(sock,fdset);
 
to.tv_sec = to.tv_usec = DELAY;
 
if (select(sock+1, fdset, NULL, NULL, &to)>0) {
 
// New connection request, accpet and create new stream-node
 
int fd = nonblocking(accept(sock, NULL, NULL));
 
if (fd>0) {
 
streamInfo *newsi = malloc(sizeof(streamInfo));
 
newsi->fd = fd;
 
newsi->inbuf = malloc(BUFSIZE);
 
newsi->outbuf = malloc(BUFSIZE);
 
newsi->inptr = 0;
 
newsi->outptr = 0;
 
//nodeSetState(newNode = add-me-to-stream-loop, STREAMINFO, newsi);
 
}
 
else logErr("accept(): failed!");
 
}
 
}
 
  
 +
// List & Node Space
 +
#include "listSpace.h"      // [[[[listSpace.c]]]]: listSpace and some C-specific extras: hash, trie, linked-list
 +
#include "nodeSpace.h"      // [[[[nodeSpace.c]]]]: NodeSpace function declarations and initialisation
 +
#include "serialise.h"      // [[[[serialise.c]]]]: Nodal-to-text and visa-versa
  
// Each of the stream nodes points to this function in its State
+
// Interface related
void client() {
+
#include "SDL.h"
 +
#include "SDL_image.h"
 +
#include "SDL_ttf.h"
 +
//#include "SDL_opengl.h"    // OpenGL example [[[[http://www.libsdl.org/cgi/docwiki.cgi/OpenGL_20Full_20Example|here]]]]
 +
#include "interface.h"      // [[[[interface.c]]]]: Layer model, video, audio, input, OpenGL
  
// Get the info for this stream ready for reading/writing a packet if necessary
+
// Peer daemon setup
streamInfo *info = nodeGetState(this, STREAMINFO);
+
#if __WIN32__
int i,fd = info->fd, inptr = info->inptr, outptr = info->outptr;
+
#include "servicate.h"      // [[[[servicate.c]]]]
char *inbuf = info->inbuf, *outbuf = info->outbuf;
+
#elif __APPLE__
 +
#include "launchd.h"        // [[[[launchd.c]]]]
 +
#elif __unix__
 +
#include "daemonise.h"      // [[[[daemonise.c]]]]
 +
#endif
  
// Data to receive?
+
// [[[[Communications]]]] related
FD_ZERO(fdset);
+
#if __WIN32__
FD_SET(fd,fdset);
+
#include <winsock.h>
to.tv_sec = to.tv_usec = DELAY;
+
#else
if (select(fd+1, fdset, NULL, NULL, &to)>0) {
+
#include <sys/socket.h>    // see [[[[http://www.opengroup.org/onlinepubs/009695399/functions/select.html|select()]]]]
// read a packet into inbuf
+
#include <sys/select.h>
if (i = recv(fd, inbuf+inptr, PAKSIZE, 0)>0) {
+
#include <netinet/in.h>
 +
#include <sys/time.h>      // for select() related stuff
 +
#include <fcntl.h>         // O_RDWR, O_NONBLOCK, F_GETFL, F_SETFL
 +
#include <netdb.h>         // for [[[[http://www.opengroup.org/onlinepubs/009695399/basedefs/netdb.h.html|hostent struct]]]]
 +
#endif
 +
#include "io.h"            // [[[[io.c]]]]: Main server and stream setup and functions
  
// test if complete message in buffer
+
int main(int argc, char **argv) {
char *message = NULL;
 
while (i--) {
 
//  /\r?\n\r?\n\x00?/
 
}
 
  
if (message) {
+
logAdd("");            // Blank line in log to separate peerd sessions
//inptr = info->inptr -= msg_size;
+
peerdInit();           // Set up as a daemon or service
// hook a process into the loop
+
listInit();            // Initialise list-space and hash/trie functions
}
+
nodeInit();            // Set up initial nodal structure for reduction loop
}
+
args(argc,argv);       // Handle command-line args and globals like peer and port
else if (i == 0) {
+
ifInit();              // Initialise interface aspects (video, audio, input, OpenGL)
// zero bytes to read, do orderly termination
+
ioInit();               // Set up listening socket on specified port
// todo: remove this stream node from loop
 
free(info);
 
}
 
else logErr("recv(): failed!");
 
}
 
  
// Data to send?
+
// Main [[[[nodal reduction]]]] loop
FD_ZERO(fdset);
+
// - maintains [[[[this]]]], [[[[parent]]]] and [[[[grandpa]]]] globals
FD_SET(fd,fdset);
+
logAdd("Handing program execution over to nodal reduction...");
to.tv_sec = to.tv_usec = DELAY;
+
while(1) nodeReduce();
if (select(fd+1, NULL, fdset, NULL, &to)>0) {
 
// write a packet from outbuf
 
int len = PAKSIZE; // or less
 
if (send(fd, outbuf+outptr, len, 0) == -1) logErr("send() failed!");
 
}
 
  
 
}
 
}
 +
</source>
 +
[[Category:C]]

Latest revision as of 15:17, 6 July 2015

Legacy.svg Legacy: This article describes a concept that has been superseded in the course of ongoing development on the Organic Design wiki. Please do not develop this any further or base work on this concept, now this page is for historic record only.
// http://www.organicdesign.co.nz/peerd - nodal p2p wiki daemon
// Source: http://www.organicdesign.co.nz/peerd/files/C - the C language version for *ix,OSX,NT platforms
// This article and all its includes are licenced under http://www.gnu.org/copyleft/lesser.html
// Compiled in Win32 by peerd.c/win32-makefile to http://www.organicdesign.co.nz/wiki/images/a/a2/Peerd.msi
// Compiled in Linux and OSX by rp to peerd.deb and peerd.dmg

// Globals
int this = 0,parent,grandpa,port = 80;
char *peer = "default";
char *file = (char*)0;

// Reserved nodes used by nodal reduction process (tmp)
#define nodeTRUE   1  // [[[[nodeTRUE]]]]
#define nodeNEXT   1  // [[[[nodeNEXT]]]]
#define nodePREV   2  // [[[[nodePREV]]]]
#define nodeCODE   3  // [[[[nodeCODE]]]] is a [[[[association|pseudo node-value]]]] to determine is the nodes non-nodal-data is a function-ref
#define nodePARENT 4  // [[[[nodePARENT]]]] updated by [[[[nodal reduction]]]], the node for which thsi is the [[[[focus]]]]
#define nodeTRIE   5  // [[[[nodeTRIE]]]] use a different root for trie/hash so it can't interfere with serialisation of nodal-root
#define nodeFIRST  6  // [[[[nodeFIRST]]]]
#define nodeLAST   7  // [[[[nodeLAST]]]]
#define nodeMAKE   8  // [[[[nodeMAKE]]]]
#define nodeINIT   9  // [[[[nodeINIT]]]]
#define nodeMAIN   10 // [[[[nodeMAIN]]]]
#define nodeEXIT   11 // [[[[nodeEXIT]]]]


#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <stdarg.h>
#include <time.h>
#include <regex.h>
#include "util.h"           // [[[[util.c]]]]: General utils, file,log,string etc

// List & Node Space
#include "listSpace.h"      // [[[[listSpace.c]]]]: listSpace and some C-specific extras: hash, trie, linked-list
#include "nodeSpace.h"      // [[[[nodeSpace.c]]]]: NodeSpace function declarations and initialisation
#include "serialise.h"      // [[[[serialise.c]]]]: Nodal-to-text and visa-versa

// Interface related
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h"
//#include "SDL_opengl.h"     // OpenGL example [[[[http://www.libsdl.org/cgi/docwiki.cgi/OpenGL_20Full_20Example|here]]]]
#include "interface.h"      // [[[[interface.c]]]]: Layer model, video, audio, input, OpenGL

// Peer daemon setup
#if __WIN32__
#include "servicate.h"      // [[[[servicate.c]]]]
#elif __APPLE__
#include "launchd.h"        // [[[[launchd.c]]]]
#elif __unix__
#include "daemonise.h"      // [[[[daemonise.c]]]]
#endif

// [[[[Communications]]]] related
#if __WIN32__
#include <winsock.h>
#else
#include <sys/socket.h>     // see [[[[http://www.opengroup.org/onlinepubs/009695399/functions/select.html|select()]]]]
#include <sys/select.h>
#include <netinet/in.h>
#include <sys/time.h>       // for select() related stuff
#include <fcntl.h>          // O_RDWR, O_NONBLOCK, F_GETFL, F_SETFL
#include <netdb.h>          // for [[[[http://www.opengroup.org/onlinepubs/009695399/basedefs/netdb.h.html|hostent struct]]]]
#endif
#include "io.h"             // [[[[io.c]]]]: Main server and stream setup and functions

int main(int argc, char **argv) {

	logAdd("");             // Blank line in log to separate peerd sessions
	peerdInit();            // Set up as a daemon or service
	listInit();             // Initialise list-space and hash/trie functions
	nodeInit();             // Set up initial nodal structure for reduction loop
	args(argc,argv);        // Handle command-line args and globals like peer and port
	ifInit();               // Initialise interface aspects (video, audio, input, OpenGL)
	ioInit();               // Set up listening socket on specified port

	// Main [[[[nodal reduction]]]] loop
	// - maintains [[[[this]]]], [[[[parent]]]] and [[[[grandpa]]]] globals
	logAdd("Handing program execution over to nodal reduction...");
	while(1) nodeReduce();

	}