OSDN Git Service

(LibGoblin)
[drdeamon64/drdeamon64.git] / deamon / drd64_debugd_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_debugd_dispatch.c
33 Function: 
34 Comment: 
35 ----------------------------------------------------------------------*/
36
37 #include"drd64_debugd.h"
38
39 static  fd_set  g_fds_orig;
40
41
42 void
43         Drd64_Debugd_Dispatch_CloseSocket(
44                 int             i_fds )
45 {
46         Drd64_Server_RecvStatus         *p_recv;
47
48         p_recv  = Drd64_Server_RecvStatus_GetRecvStatus( i_fds );
49         assert( NULL != p_recv );
50
51         close( i_fds );
52         FD_CLR( i_fds, &g_fds_orig );
53         Drd64_Server_RecvStatus_DeleteSocketsChain( p_recv );
54         Drd64_Server_RecvStatus_CloseRecvStatus( i_fds );
55         DRD64_DEBUG_PRINT("CloseSocket",i_fds,"errono",errno,NULL,0);
56
57         return;
58 }
59
60
61 int
62         Drd64_Debugd_Dispatch_OpenSocket(
63                 int i_socket_server )
64 {
65         int             i_socket_new;
66         Drd64_Server_RecvStatus         *p_recv;
67
68         i_socket_new    = accept( i_socket_server, NULL, NULL );
69         DRD64_DEBUG_SYSCALL("accept(New Comm.)",i_socket_new,errno);
70
71         if( -1 == i_socket_new )        {
72                 return -1;
73         }
74
75         FD_SET( i_socket_new, &g_fds_orig );
76
77         p_recv = Drd64_Server_RecvStatus_AllocRecvStatus(
78                                         i_socket_new, DRD64_DEBUGD_RECVSTATUS_UNITS );
79
80         if( NULL == p_recv )    {
81                 return -2;
82         }
83
84         Drd64_Server_RecvStatus_InitRecvStatus( p_recv, i_socket_new );
85         Drd64_Server_RecvStatus_AddSocketsChain( p_recv );
86
87         return  i_socket_new;
88 }
89
90
91 int
92         Drd64_Debugd_Dispatch_ExecPacket(
93                 int             i_recv_id,
94                 Drd64_Server_RecvStatus *p_recv,
95         Drd64_Debugd_MasterInformation *p_debugd )
96 {
97         int             i_result;
98         Drd64_PacketHeader                      *p_phead;
99         Drd64_Server_RecvStatus         *p_recv_parent;
100         void                                            *pv_data;
101
102         /* Phase 1 : Init. ================================*/
103         pv_data                 = NULL;
104         i_result        = DRD64_DEBUGD_DISPATCH_RESULT_CLOSE;
105
106         p_phead = (Drd64_PacketHeader *)p_recv->pv_buf;
107         assert( NULL != p_phead );
108
109         if( 0 < p_phead->i_datalen )
110                 { pv_data       = DRD64_PacketData( p_recv->pv_buf ); }
111
112
113         /* Phase 2 : Exec. Command ========================*/
114         /* CMD: Connect -----------------------------------*/
115         if( DRD64_COMMAND_CONNECT == p_phead->dw_command )      {
116                 //i_result = Drd64_Debugd_Cmd_Connect( i_recv_id, p_phead, pv_data );
117         }
118         /* CMD: DisConnect --------------------------------*/
119         else if( DRD64_COMMAND_DISCONNECT == p_phead->dw_command )      {
120         }
121         /* CMD: Attach Link -------------------------------*/
122         else if( DRD64_COMMAND_ATTACH_LINK == p_phead->dw_command )     {
123                 i_result        = Drd64_Debugd_Cmd_AttachLink(
124                                                         i_recv_id, p_phead, pv_data, p_debugd );
125         }
126         /* CMD: Attach Report -----------------------------*/
127         else if( DRD64_COMMAND_ATTACH_REPORT == p_phead->dw_command )   {
128                 i_result        = Drd64_Debugd_Cmd_AttachReport(
129                                                         i_recv_id, p_phead, pv_data, p_debugd );
130         }
131         /* CMD: Detach ------------------------------------*/
132         else if( DRD64_COMMAND_DETACH == p_phead->dw_command )  {
133                 i_result        = Drd64_Debugd_Cmd_Detach(
134                                                         i_recv_id, p_phead, p_debugd );
135         }
136         /* CMD: No Support Command ------------------------*/
137         else    {
138
139         }
140
141         /* Phase 3 : Result Proc.  =======================*/
142         if( DRD64_DEBUGD_DISPATCH_RESULT_RESTART == i_result )  {
143                 if( -1 < p_phead->i_rid_resume )        {
144                         p_recv_parent = Drd64_Server_RecvStatus_GetRecvStatus(
145                                                                 p_phead->i_rid_resume );
146                         assert( NULL != p_recv_parent );
147
148                         p_recv_parent->b_recv_status
149                                         = DRD64_SERVER_RECVSTATUS_STATUS_RESUME;
150                 }
151         }
152         else if( DRD64_DEBUGD_DISPATCH_RESULT_POLL == i_result )        {
153                 p_recv->b_recv_status   = DRD64_SERVER_RECVSTATUS_STATUS_STOP;
154         }
155
156         if(( DRD64_DEBUGD_DISPATCH_RESULT_COMPLETE == i_result )
157                         || ( DRD64_DEBUGD_DISPATCH_RESULT_RESTART == i_result ))
158                 { Drd64_Server_RecvStatus_DeleteResumeChain( i_recv_id ); }
159
160         return i_result;
161 }
162
163
164 int
165         Drd64_Debugd_Dispatch_JudgePacket(
166                 int             i_fds,
167                 int             i_remainbytes,
168                 Drd64_Server_RecvStatus *p_recv,
169         Drd64_Debugd_MasterInformation *p_debugd )
170 {
171         int             i_result;
172         int             i_recv_id;
173         Drd64_PacketHeader                      *p_phead;
174         Drd64_Server_RecvStatus         *p_recv_new;
175
176         i_result                = 0x00;
177
178         /* Judge 1: Receiving : Remain Bytes Receiving = 0x01 */
179         if( 0 < i_remainbytes )
180                 { return DRD64_DEBUGD_DISPATCH_RESULT_RECEVING; }
181
182         /* Judge 2: Error: Connection Down or Close = 0x00 */
183         else if( 0 > i_remainbytes )
184                 { return DRD64_DEBUGD_DISPATCH_RESULT_CLOSE; }
185
186         p_phead = (Drd64_PacketHeader *)p_recv->pv_buf;
187         assert( NULL != p_phead );
188
189         /* Check 1 : Header Check */
190         if( DRD64_PACKET_HEADER != p_phead->w_header )
191                 { return DRD64_DEBUGD_DISPATCH_RESULT_CLOSE; }
192
193         /* Judge 3: Remain Packet Data? = 0x01 */
194         if(( DRD64_SERVER_RECVSTATUS_PHASE_HEADER == p_recv->i_read_phase ) &&
195                         ( 0 < p_phead->i_datalen ))             {
196                 p_recv->i_read_phase    = DRD64_SERVER_RECVSTATUS_PHASE_DATA;
197
198                 /* Check BOF Attack */
199                 if( DRD64_MAX_PACKET_DATA < p_phead->i_datalen )
200                         { return DRD64_DEBUGD_DISPATCH_RESULT_CLOSE; }
201                 p_recv->i_remain_bytes  = p_phead->i_datalen;
202                 
203                 return DRD64_DEBUGD_DISPATCH_RESULT_RECEVING;
204         }
205
206         /* Check 2: Standart Packet Header Check */
207                 /* XXX : NO implement */
208
209         /* Check 4: Transport Packet? */
210
211
212         /* Push Readed Command Packet for Resume Pool */
213         Drd64_Server_RecvStatus_DeleteSocketsChain( p_recv );
214         i_recv_id       = Drd64_Server_RecvStatus_PushResumeChain(
215                                         i_fds, DRD64_DEBUGD_RECVSTATUS_UNITS );
216         if( 0 > i_recv_id )
217                 { return DRD64_DEBUGD_DISPATCH_RESULT_CLOSE; }    // XXX > error
218
219         p_recv_new  = Drd64_Server_RecvStatus_GetRecvStatus( i_fds );
220         assert( NULL != p_recv_new );
221
222         Drd64_Server_RecvStatus_InitRecvStatus( p_recv_new, p_recv->i_fds_id );
223         Drd64_Server_RecvStatus_AddSocketsChain( p_recv_new );
224
225         /* Exec Packet by Command-Code */
226         i_result = Drd64_Debugd_Dispatch_ExecPacket( i_recv_id, p_recv, p_debugd );
227
228         return i_result;
229 }
230
231
232 int
233         Drd64_Debugd_Dispatch_ExecResumeRecvStatus(
234                 Drd64_Debugd_MasterInformation *p_debugd )
235 {
236         int             i_result;
237         Drd64_Server_RecvStatus         *p_recv;
238
239         p_recv  = Drd64_Server_RecvStatus_GetResumeChainStart();
240         while( NULL != p_recv ) {
241                 if( DRD64_SERVER_RECVSTATUS_STATUS_RESUME
242                                                         == p_recv->b_recv_status )  {
243
244                         i_result = Drd64_Debugd_Dispatch_ExecPacket(
245                                                         p_recv->i_recvstatus_id, p_recv, p_debugd );
246
247                         /* 0x00 = Judge 1 : Disconnect ( Others Packet ) */
248                         if( DRD64_DEBUGD_DISPATCH_RESULT_CLOSE == i_result )
249                                 { Drd64_Debugd_Dispatch_CloseSocket( p_recv->i_fds_id ); }
250                         else if( DRD64_DEBUGD_DISPATCH_RESULT_RESTART == i_result )
251                                 { p_recv  = NULL; }
252                 }
253
254                 if( NULL != p_recv )
255                         { p_recv = (Drd64_Server_RecvStatus *)p_recv->pv_recv_next; }
256                 else
257                         { p_recv  = Drd64_Server_RecvStatus_GetResumeChainStart(); }
258         }
259
260         return 0x00;
261 }
262
263
264
265 int
266     Drd64_Debugd_Dispatch_Polling(
267         Drd64_Debugd_MasterInformation *p_debugd )
268 {
269         fd_set  fds_now;
270         //int     i_cnt;
271         int             i_socket;
272         int             i_result;
273         int             i_err;
274         int             i_pid;
275         int             i_selects;
276         //int     i_socket_new;
277         int             i_selects_base;
278         int     i_selects_max;
279         int             i_selects_last;
280         int             i_resume_flag;
281         Drd64_Server_RecvStatus         *p_recv;
282         struct  timeval         tm_val;
283
284         FD_ZERO( &g_fds_orig );
285         FD_SET( p_debugd->i_socket_debugd, &g_fds_orig );
286
287         i_selects_base = p_debugd->i_socket_debugd + 1;
288         i_selects_max = i_selects_base;
289
290         tm_val.tv_sec   = 0;
291         tm_val.tv_usec  = 5000;
292
293         while( 1 )  {
294                 /* Phase 1: Packet & Signal Polling */
295                 memcpy( &fds_now, &g_fds_orig, sizeof( struct fd_set ) );
296                 i_selects       = select( i_selects_max, &fds_now, NULL, NULL, &tm_val );
297         
298                 /* Phase 2: Receive Packet */
299                 if( 0 < i_selects )     {
300                         /* Server Socket from Local( Client or Marshald ) */
301                         if( FD_ISSET( p_debugd->i_socket_debugd, &fds_now ) )  {
302                                 Drd64_Debugd_Dispatch_OpenSocket(
303                                                                         p_debugd->i_socket_debugd );
304                 i_selects--;
305                         }
306
307                         i_resume_flag   = 0x00;
308                         p_recv  = Drd64_Server_RecvStatus_GetSocketsChainStart();
309                         while(( NULL != p_recv ) && ( 0 < i_selects ))  {
310                                 
311                                 i_socket        = p_recv->i_fds_id;
312
313                                 if( FD_ISSET( i_socket, &fds_now ) )    {
314                                         /* Read */
315                                         i_err = Drd64_Server_RecvSocket_SocketRead_Cert(
316                                                                                                         i_socket, &i_pid );
317                                         DRD64_DEBUG_PRINT("SocketRead",i_err,"FD",
318                                                                                         i_socket,"SrcPID",i_pid);
319                                         i_selects--;
320
321                                         /* Judge Packet */
322                                         i_result = Drd64_Debugd_Dispatch_JudgePacket(
323                                                                                 i_socket, i_err, p_recv, p_debugd );
324
325                                         /* 0x00 = Judge 1 : Disconnect ( Others Packet ) */
326                                         if( DRD64_DEBUGD_DISPATCH_RESULT_CLOSE == i_result )
327                                                 { Drd64_Debugd_Dispatch_CloseSocket( i_socket ); }
328                                         /* 0x03 = Judge 2 : Restart Flag ON */
329                                         else if( DRD64_DEBUGD_DISPATCH_RESULT_RESTART == i_result )
330                                                 { i_resume_flag = 0x01; }
331                                         else if( DRD64_DEBUGD_DISPATCH_RESULT_TERMINATE
332                                                                                                         == i_result )    {
333                                                 p_debugd->i_flag_terminate = 0xff;
334                                                 break;
335                                         }
336                                         /* 0x01 = Judge 1 : Reading Next */
337                                 }
338
339                                 p_recv  = (Drd64_Server_RecvStatus *)p_recv->pv_recv_next;
340                         }
341
342                         /* Check Terminate Flag => break while loop */
343                         if( 0x00 != p_debugd->i_flag_terminate )        { break; }
344                         
345                         /* Check Restart Packet (RecvStatus) */
346                         if( 0x00 != i_resume_flag )
347                                 { Drd64_Debugd_Dispatch_ExecResumeRecvStatus( p_debugd ); }
348
349                         /* Set Max fd */
350                         i_selects_last  = Drd64_Server_RecvStatus_GetRecvStatMax();
351                         if( i_selects_last > i_selects_base )
352                                 { i_selects_max = i_selects_last; }
353                         else
354                                 { i_selects_max = i_selects_base; }
355                 }
356
357                 /* Phase 3: Dispatch Complete-Received Packet */
358
359                 /* Phase 4: Signal Check & Proc */
360
361                 /* Check Terminate Flag => break while loop */
362                 if( 0x00 != p_debugd->i_flag_terminate )        { break; }
363         }
364         
365         return 0x00;
366 }
367
368
369 /* EOF of drd64_.c ----------------------------------- */