Base architecture.
[brdnet.git] / ServerLoop.pas
blob8c4f8650edc3da553c047d019ba24c17aaaf3232
1 UNIT ServerLoop;
3 INTERFACE
4 uses MemStream,NetAddr;
6 procedure Loop;
8 type tSMsg=object
9 Source: ^tNetAddr;
10 Length: {Long}Word;
11 Data: pointer;
12 stream: tMemoryStream;
13 channel: word;
14 end;
16 type tMessageHandler=procedure(msg:tSMsg);
18 procedure SetOpcodeMsgHandler(OpCode:byte; handler:tMessageHandler);
19 procedure SetHiMsgHandler(handler:tMessageHandler);
21 IMPLEMENTATION
23 USES SysUtils,Sockets,UnixType,BaseUnix
26 {aim for most simple implementation, since could be extended anytime}
28 var s_inet:tSocket;
29 var pollArr: array [0..0] of tPollFd;
31 procedure SC(fn:pointer; retval:cint);
32 begin
33 if retval < 0 then begin
34 raise eXception.Create(Format('Socket error %d operation %P',[SocketError,fn]));
35 end;
36 end;
38 procedure s_SetupInet;
39 var bind_addr:tInetSockAddr;
40 begin
41 with bind_addr do begin
42 family:=AF_INET;
43 port:=htons(3511);
44 addr:=0; {any}
45 s_inet:=fpSocket(family,SOCK_DGRAM,IPPROTO_UDP);
46 SC(@fpSocket,s_inet);
47 end;
48 SC(@fpBind,fpBind(s_inet,@bind_addr,sizeof(bind_addr)));
49 with PollArr[0] do begin
50 fd:=s_inet;
51 events:=pollIN or pollERR;
52 revents:=0;
53 end;
54 end;
56 var Terminated:boolean=false;
58 procedure SendMessage(const data; len:word; const rcpt:tSockAddr );
59 var rc:Integer;
60 begin
61 SC(@fpsendto,fpsendto(s_inet,@data,len,0,@rcpt,sizeof(sockaddr_in)));
62 end;
64 procedure HandleMsg(s:tSocket; const buffer; len:LongWord; from:tSockAddr);
65 begin
66 writeln;
67 write('HandleMsg: ');
68 if len<1 then exit;
69 case char((@buffer+0)^) of
70 'b':writeln('Brod-Net');
71 'd':begin
72 writeln('Mainline DHT');
73 RPC.SendMessage:=@SendMessage;
74 RPC.ReceiveMessage(buffer,len,from);
75 end;
76 else writeln('Unknown');
77 end;
78 end;
80 procedure SignalHandler(sig:cint);CDecl;
81 begin
82 writeln;
83 if terminated then raise eControlC.Create('CtrlC DoubleTap') ;
84 Terminated:=true;
85 writeln('Shutdown requested');
86 end;
88 procedure Loop;
89 var EventsCount:integer;
90 var Buffer:array [1..1024] of byte;
91 var pkLen:LongWord;
92 var From:tSockAddr;
93 var FromLen:LongWord;
94 begin
95 EventsCount:=fpPoll(@PollArr[0],1,5000);
96 if eventscount=0 then write('.') else begin
97 {INET socket}
98 with PollArr[0] do begin
99 if (revents and pollIN)>0 then begin
100 FromLen:=sizeof(From);
101 pkLen:=fprecvfrom(s_inet,@Buffer,sizeof(Buffer),0,@from,@fromlen);
102 SC(@fprecvfrom,fromlen);
103 HandleMsg(s_inet,Buffer,pkLen,from);
104 revents:=0;
105 end;
106 end;
107 {INET6...}
108 end;
109 end;
111 BEGIN
112 s_setupInet;
113 fpSignal(SigInt,@SignalHandler);
114 fpSignal(SigTerm,@SignalHandler);
115 repeat Loop until Terminated;
116 write('Standard terminate [');
117 CloseSocket(s_inet);
118 writeln(']');
119 END.