OSDN Git Service

(LibGoblin)
[drdeamon64/drdeamon64.git] / deamon / drd64_marshald_dispatch.c
1 /*DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64
2
3                          D r . D e a m o n  6 4
4                         for INTEL64(R), AMD64(R)
5         
6    Copyright(C) 2007-2009 Koine Yuusuke(koinec). All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10
11  1. Redistributions of source code must retain the above copyright notice,
12     this list of conditions and the following disclaimer.
13  2. Redistributions in binary form must reproduce the above copyright
14     notice, this list of conditions and the following disclaimer in the
15     documentation and/or other materials provided with the distribution.
16
17 THIS SOFTWARE IS PROVIDED BY Koine Yuusuke(koinec) ``AS IS'' AND ANY
18 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL Koine Yuusuke(koinec) OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64*/
30
31 /* File Info -----------------------------------------------------------
32 File: drd64_marshald_dispatch.c
33 Function: Marshald Command Dispatcher (Main Loop Routine) 
34 Comment: 
35 ----------------------------------------------------------------------*/
36
37 #include"drd64_marshald.h"
38
39 static  fd_set  g_fds_orig;
40
41
42 /* for EXTERNAL Function */
43 void
44         Drd64_Marshald_Dispatch_SetFD(
45                 int     i_fds )
46 {
47         FD_SET( i_fds, &g_fds_orig );
48         return;
49 }
50
51
52 /* for EXTERNAL Function */
53 void
54         Drd64_Marshald_Dispatch_CloseSocket(
55                 int     i_fds )
56 {
57         Drd64_Server_RecvStatus *p_recv;
58         Drd64_Marshald_ConnectInfo      *p_cinfo;
59
60         p_recv = Drd64_Server_RecvStatus_GetRecvStatus( i_fds );
61         assert( NULL != p_recv );
62
63         if( NULL != p_recv->pv_cinfo_connection )       {
64                 p_cinfo = (Drd64_Marshald_ConnectInfo *)p_recv->pv_cinfo_connection;
65
66                 Drd64_Marshald_Cinfo_FreeConnectInfo( p_cinfo );
67                 p_recv->pv_cinfo_connection     = NULL;
68                 p_cinfo = NULL;
69                 DRD64_LOG_DEBUG("  [DEBUG] Free ConnectionInfo with Close");
70         }
71
72         close( i_fds );
73         FD_CLR( i_fds, &g_fds_orig );
74         Drd64_Server_RecvStatus_DeleteSocketsChain( p_recv );
75         Drd64_Server_RecvStatus_CloseRecvStatus( i_fds );
76         DRD64_DEBUG_PRINT("CloseSocket",i_fds,"FD",i_fds,"errono",errno);
77
78         return;
79 }
80
81
82 int
83         Drd64_Marshald_Dispatch_OpenSocket(
84                 int     i_socket_server )
85 {
86         int             i_socket_new;
87         Drd64_Server_RecvStatus         *p_recv;
88
89         i_socket_new    = accept( i_socket_server, NULL, NULL );
90         DRD64_DEBUG_SYSCALL("accept(New Comm.)",i_socket_new,errno);
91
92         if( -1 == i_socket_new )        {
93                 return -1;
94         }
95
96         FD_SET( i_socket_new, &g_fds_orig );
97
98         p_recv = Drd64_Server_RecvStatus_AllocRecvStatus(
99                                         i_socket_new, DRD64_MARSHALD_RECVSTATUS_UNITS );
100
101         if( NULL == p_recv )    {
102                 return -2;
103         }
104
105         Drd64_Server_RecvStatus_InitRecvStatus( p_recv, i_socket_new );
106         Drd64_Server_RecvStatus_AddSocketsChain( p_recv );
107
108         return i_socket_new;
109 }
110
111
112 /*----------------------------------------------------------------------
113 ----------------------------------------------------------------------*/
114 int
115         Drd64_Marshald_Dispatch_ExecPacket(
116                 int             i_recv_id,
117                 Drd64_Server_RecvStatus *p_recv,
118         Drd64_Marshald_MasterInformation *p_marshald )
119 {
120         int                                                     i_result;
121         Drd64_PacketHeader                      *p_phead;
122         Drd64_Server_RecvStatus         *p_recv_parent;
123         void                                            *pv_data;
124
125         /* Phase 1 : Init. ================================*/
126         pv_data                 = NULL;
127         i_result        = DRD64_MARSHALD_DISPATCH_RESULT_CLOSE;         // XXX > error
128
129         p_phead = (Drd64_PacketHeader *)p_recv->pv_buf;
130         assert( NULL != p_phead );
131
132         if( 0 < p_phead->i_datalen )
133                 { pv_data       = DRD64_PacketData( p_recv->pv_buf ); }
134
135
136         /* Phase 2 : Exec. Command ========================*/
137         /* CMD: Connect -----------------------------------*/
138         if( DRD64_COMMAND_CONNECT == p_phead->dw_command )      {
139                 i_result = Drd64_Marshald_Cmd_Connect(
140                                                         i_recv_id, p_phead, pv_data );
141         }
142         /* CMD: Connect Count -----------------------------*/
143         else if( DRD64_COMMAND_CONNECT_COUNT == p_phead->dw_command )   {
144                 i_result = Drd64_Marshald_Cmd_ConnectCount(
145                                                         i_recv_id, p_phead, pv_data );
146         }
147         /* CMD: DisConnect --------------------------------*/
148         else if( DRD64_COMMAND_DISCONNECT == p_phead->dw_command )      {
149                 i_result = Drd64_Marshald_Cmd_DisConnect( i_recv_id, p_phead, pv_data );
150         }
151         /* CMD: Attach Request  ---------------------------*/
152         else if( DRD64_COMMAND_ATTACH_REQUEST == p_phead->dw_command )  {
153                 i_result = Drd64_Marshald_Cmd_AttachRequest(
154                                                         i_recv_id, p_phead, pv_data, p_marshald );
155         }
156         /* CMD: Attach Link  ------------------------------*/
157         else if( DRD64_COMMAND_ATTACH_LINK == p_phead->dw_command )     {
158                 i_result = Drd64_Marshald_Cmd_AttachLink(
159                                                         i_recv_id, p_phead, pv_data, p_marshald );
160         }
161         /* CMD: Attach Report -----------------------------*/
162         else if( DRD64_COMMAND_ATTACH_REPORT == p_phead->dw_command )   {
163                 i_result = Drd64_Marshald_Cmd_AttachReport(
164                                                         i_recv_id, p_phead, pv_data, p_marshald );
165         }
166         else if( DRD64_COMMAND_DETACH == p_phead->dw_command )  {
167                 i_result = Drd64_Marshald_Cmd_Detach(
168                                                         i_recv_id, p_phead, pv_data, p_marshald );
169         }
170         else if( DRD64_COMMAND_EXIT == p_phead->dw_command )    {
171         }
172         else if( DRD64_COMMAND_DEBUGD_BOOTINFO == p_phead->dw_command ) {
173                 i_result = Drd64_Marshald_Msg_DebugdBootInfo(
174                                                         i_recv_id, p_phead, pv_data, p_marshald );
175         }
176
177
178         /* Phase 3 : Result Proc.  =======================*/
179         if( DRD64_MARSHALD_DISPATCH_RESULT_RESTART == i_result )        {
180                 if( -1 < p_phead->i_rid_resume )        {
181                         p_recv_parent = Drd64_Server_RecvStatus_GetRecvStatus(
182                                                                         p_phead->i_rid_resume );
183                         assert( NULL != p_recv_parent );
184
185                         p_recv_parent->b_recv_status
186                                         = DRD64_SERVER_RECVSTATUS_STATUS_RESUME;
187                 }
188         }
189         else if( DRD64_MARSHALD_DISPATCH_RESULT_POLL == i_result )      {
190                 p_recv->b_recv_status   = DRD64_SERVER_RECVSTATUS_STATUS_STOP;
191         }
192
193         /* XXX > error */
194         if(( DRD64_MARSHALD_DISPATCH_RESULT_COMPLETE == i_result )
195                         || ( DRD64_MARSHALD_DISPATCH_RESULT_RESTART == i_result ))      {
196                 Drd64_Server_RecvStatus_DeleteResumeChain( i_recv_id );
197         }
198
199         return i_result;
200 }
201
202
203 int
204         Drd64_Marshald_Dispatch_JudgePacket(
205                 int             i_fds,
206                 int             i_remainbytes,
207                 Drd64_Server_RecvStatus *p_recv,
208         Drd64_Marshald_MasterInformation *p_marshald )
209 {
210         int             i_result;
211         int             i_recv_id;
212         Drd64_PacketHeader                      *p_phead;
213         Drd64_Server_RecvStatus         *p_recv_new;
214
215         i_result                = 0x00;
216
217         /* Judge 1: Receiving : Remain Bytes Receiving = 0x01 */
218         if( 0 < i_remainbytes )
219                 { return DRD64_MARSHALD_DISPATCH_RESULT_RECEVING; }
220         /* Judge 2: Error: Connection Down or Close = 0x00 */
221         else if( 0 > i_remainbytes )
222                 { return DRD64_MARSHALD_DISPATCH_RESULT_CLOSE; }
223
224         p_phead = (Drd64_PacketHeader *)p_recv->pv_buf;
225         assert( NULL != p_phead );
226
227         /* Check 1 : Header Check */
228         if( DRD64_PACKET_HEADER != p_phead->w_header )
229                 { return DRD64_MARSHALD_DISPATCH_RESULT_CLOSE; }
230
231         /* Judge 3: Remain Packet Data? = 0x01 */
232         if(( DRD64_SERVER_RECVSTATUS_PHASE_HEADER == p_recv->i_read_phase ) &&
233                         ( 0 < p_phead->i_datalen ))             {
234                 p_recv->i_read_phase    = DRD64_SERVER_RECVSTATUS_PHASE_DATA;
235
236                 /* Check BOF Attack */
237                 if( DRD64_MAX_PACKET_DATA < p_phead->i_datalen )
238                         { return DRD64_MARSHALD_DISPATCH_RESULT_CLOSE; }
239                 p_recv->i_remain_bytes  = p_phead->i_datalen;
240                 
241                 return DRD64_MARSHALD_DISPATCH_RESULT_RECEVING;
242         }
243
244         /* Check 2: Standart Packet Header Check */
245                 /* XXX : NO implement */
246
247         /* Check 4: Relay Debugd-Cmd Packet? */
248
249         /* Push Readed Command Packet for Resume Pool */
250         Drd64_Server_RecvStatus_DeleteSocketsChain( p_recv );
251         i_recv_id       = Drd64_Server_RecvStatus_PushResumeChain(
252                                                 i_fds, DRD64_MARSHALD_RECVSTATUS_UNITS );
253         if( 0 > i_recv_id )
254                 { return DRD64_MARSHALD_DISPATCH_RESULT_CLOSE; }        // XXX > error
255
256         p_recv_new      = Drd64_Server_RecvStatus_GetRecvStatus( i_fds );
257         assert( NULL != p_recv_new );
258
259         Drd64_Server_RecvStatus_InitRecvStatus( p_recv_new, p_recv->i_fds_id );
260         Drd64_Server_RecvStatus_AddSocketsChain( p_recv_new );
261         Drd64_Server_RecvStatus_SetConnectionInfoPointer(
262                                     p_recv_new, p_recv->pv_cinfo_connection );
263         
264         /* Exec Packet by Command-Code */
265         i_result = Drd64_Marshald_Dispatch_ExecPacket(
266                                                 i_recv_id, p_recv, p_marshald );
267
268         return i_result;
269 }
270
271
272 int
273         Drd64_Marshald_Dispatch_ExecResumeRecvStatus(
274                 Drd64_Marshald_MasterInformation *p_marshald )
275 {
276         int                                                     i_result;
277         Drd64_Server_RecvStatus         *p_recv;
278
279         DRD64_LOG_DEBUG("  [DEBUG] Dispatch : Exec Resume RecvStatus Start");
280
281         p_recv  = Drd64_Server_RecvStatus_GetResumeChainStart();
282         while( NULL != p_recv ) {
283                 if( DRD64_SERVER_RECVSTATUS_STATUS_RESUME
284                                                         == p_recv->b_recv_status )      {
285
286                         DRD64_LOG_DEBUG("    [DEBUG] Dispatch : Do Resume RecvStatus");
287                         i_result = Drd64_Marshald_Dispatch_ExecPacket(
288                                                         p_recv->i_recvstatus_id, p_recv, p_marshald );
289
290                         /* XXX : support for disconnect (CLOSE) */
291                         /* 0x00 = Judge 1 : Disconnect ( Others Packet ) */
292                         if( DRD64_MARSHALD_DISPATCH_RESULT_CLOSE == i_result )  {
293                                 Drd64_Marshald_Dispatch_CloseSocket( p_recv->i_fds_id );
294                         }
295                         else if( DRD64_MARSHALD_DISPATCH_RESULT_RESTART == i_result )   {
296                                 p_recv  = NULL;
297                         }
298                 }
299                                         
300                 if( NULL != p_recv )    {
301                         p_recv = (Drd64_Server_RecvStatus *)p_recv->pv_recv_next;
302                 }
303                 else    {
304                         p_recv  = Drd64_Server_RecvStatus_GetResumeChainStart();
305                 }
306         }
307
308         DRD64_LOG_DEBUG("  [DEBUG] Dispatch : Exec Resume RecvStatus Ended");
309
310         return 0x00;
311 }
312
313 int
314     Drd64_Marshald_Dispatch_Polling(
315         Drd64_Marshald_MasterInformation *p_marshald )
316 {
317         fd_set  fds_now;
318         //int     i_cnt;
319         int             i_socket;
320         int             i_result;
321         int             i_err;
322         int             i_pid;
323         int             i_selects;
324         int             i_resume_flag;
325         int             i_selects_base;
326         int     i_selects_max;
327         int             i_selects_last;
328         Drd64_Server_RecvStatus         *p_recv;
329         struct  timeval                         tmval;
330
331         FD_ZERO( &g_fds_orig );
332         FD_SET( p_marshald->i_socket_local, &g_fds_orig );
333         FD_SET( p_marshald->i_socket_inet, &g_fds_orig );
334
335         if( p_marshald->i_socket_local > p_marshald->i_socket_inet )
336                 { i_selects_base        = p_marshald->i_socket_local + 1; }
337         else
338                 { i_selects_base        = p_marshald->i_socket_inet + 1; }
339         i_selects_max = i_selects_base;
340
341         tmval.tv_sec    = 0;
342         tmval.tv_usec   = 5000;
343
344         while( 1 )  {
345                 /* Phase 1: Packet & Signal Polling */
346                 memcpy( &fds_now, &g_fds_orig, sizeof( struct fd_set ) );
347                 i_selects = select( i_selects_max, &fds_now, NULL, NULL, &tmval );
348         
349                 /* Phase 2: Receive Packet */
350                 if( 0 < i_selects )             {
351
352                         /* Server Socket from Local */
353                         if( FD_ISSET( p_marshald->i_socket_local, &fds_now ))   {
354                                 Drd64_Marshald_Dispatch_OpenSocket(
355                                                                 p_marshald->i_socket_local );
356                                 i_selects--;
357                         }
358
359                         /* Server Socket from INet */
360                         if( FD_ISSET( p_marshald->i_socket_inet, &fds_now ))    {
361                                 Drd64_Marshald_Dispatch_OpenSocket(
362                                                                 p_marshald->i_socket_inet );
363                                 i_selects--;
364                         }
365
366                         i_resume_flag   = 0x00; 
367                         p_recv  = Drd64_Server_RecvStatus_GetSocketsChainStart();
368                         while(( NULL != p_recv ) && ( 0 < i_selects ))  {
369
370                                 i_socket        = p_recv->i_fds_id;
371
372                                 if( FD_ISSET( i_socket, &fds_now ) )    {
373                                         /* Read */
374                                         assert( DRD64_SERVER_RECVSTATUS_STATUS_READ
375                                                                                 == p_recv->b_recv_status );
376                 
377                                         /*i_err = Drd64_Server_RecvSocket_SocketRead_Cert(
378                                                                         i_socket, &i_pid );*/
379                                         i_err = Drd64_Server_RecvSocket_SocketRead( i_socket );
380                                         DRD64_DEBUG_PRINT("SocketRead",i_err,"FD",i_socket,"DestPid",i_pid);
381                                         i_selects--;
382
383                                         /* Judge Packet */
384                                         i_result = Drd64_Marshald_Dispatch_JudgePacket(
385                                                                 i_socket, i_err, p_recv, &drd64_marshald_info );
386
387                                         /* 0x00 = Judge 1 : Disconnect ( Others Packet ) */
388                                         if( DRD64_MARSHALD_DISPATCH_RESULT_CLOSE == i_result )  {
389                                                         Drd64_Marshald_Dispatch_CloseSocket( i_socket );
390                                         }
391                                         else if( DRD64_MARSHALD_DISPATCH_RESULT_RESTART
392                                                                                                                         == i_result )
393                                                 { i_resume_flag = 0x01; }
394                                         /* 0x01 = Judge 1 : Reading Next */
395
396                                 }
397
398                                 p_recv  = (Drd64_Server_RecvStatus *)p_recv->pv_recv_next;
399                         }
400
401                         /* Check Restart Packet (RecvStatus) */
402                         if( 0x00 != i_resume_flag )             {
403                                 Drd64_Marshald_Dispatch_ExecResumeRecvStatus(
404                                                                                 &drd64_marshald_info );
405                         }
406
407                         /* Set Max fd */
408                         i_selects_last  = Drd64_Server_RecvStatus_GetRecvStatMax();
409                         if( i_selects_last > i_selects_base )
410                                 { i_selects_max = i_selects_last; }
411                         else
412                                 { i_selects_max = i_selects_base; }
413                 }
414
415                 /* Phase 3: Check TimeOut Resume Packet */
416
417                 /* Phase 4: Signal Check & Proc */
418         }
419         
420         return 0x00;
421 }
422
423
424 /* EOF of drd64_.c ----------------------------------- */