OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [librdbg/] [src/] [servtsp.c] - Blame information for rev 173

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 **************************************************************************
3
 *
4
 *  Component:  RDBG
5
 *  Module:     servtsp.c
6
 *
7
 *  Synopsis:   Transport management for remote debug server.
8
 *
9
 * $Id: servtsp.c,v 1.2 2001-09-27 12:02:01 chris Exp $
10
 *
11
 **************************************************************************
12
 */
13
 
14
#include <sys/errno.h>
15
#include <rdbg/rdbg.h>  
16
#include <rdbg/servrpc.h>
17
#include <signal.h>             
18
#include <rpc/rpc.h>            
19
#include <rpc/svc.h>            
20
#include <netinet/in.h>         
21
#include <sys/socket.h>         
22
 
23
static int      out_sock;
24
static int      warm_test;
25
 
26
static void TimeTestHandler();
27
 
28
    /*
29
     *  TspInit - Initialize the transport system.
30
     *
31
     */
32
 
33
    void
34
TspInit (int id)
35
{
36
    struct sigaction sa;
37
 
38
        /* setup a socket to send event messages back through */
39
    out_sock = socket (PF_INET, SOCK_DGRAM, 0);
40
    if (out_sock < 0) {
41
        DPRINTF (("TspInit: socket() failed %d errno %d\n",
42
                out_sock, getErrno()));
43
        return;         /* failed to open socket, let caller deal with */
44
    }
45
    {
46
        struct sockaddr_in addr;
47
 
48
        bzero ((void *)(&addr), sizeof addr);
49
        addr.sin_family = AF_INET;
50
        addr.sin_port = htons (BackPort);
51
        if (bind (out_sock, (struct sockaddr*) &addr, sizeof addr) < 0) {
52
            DPRINTF (("TspInit: bind() failed\n"));
53
        }
54
    }
55
    /* setup alarm timer for warm testing */
56
    memset (&sa, 0, sizeof (sa));
57
    sa.sa_handler = TimeTestHandler;
58
    sigaction (SIGALRM, &sa, 0);
59
}
60
 
61
    /*
62
     *  TspTranslateRpcAddr - translate from an RPC handle to an
63
     *                        opaque address.
64
     *
65
     *  Converts the sender's address into the opaque data structure
66
     *  used for network addresses. This is used to look up the sender
67
     *  on each call.
68
     */
69
 
70
    Boolean
71
TspTranslateRpcAddr (struct svc_req* rqstp, NET_OPAQUE* opaque)
72
{
73
    struct sockaddr_in* addr;   /* used as template to extract net info */
74
    unsigned char*      up;
75
 
76
    memset (opaque, 0, sizeof (NET_OPAQUE));
77
        /*
78
         *  We interpret the remote address as a standard netbuf name.
79
         *  The format is 2 bytes of address family (normally AF_INET)
80
         *  and then a length (5) and then the IP address.
81
         */
82
    if (rqstp->rq_xprt->xp_addrlen != 16)
83
    {
84
        DPRINTF (("TspTranslateRpcAddr: Unknown remote address!!!\n"));
85
        setErrno (EPROTONOSUPPORT);
86
        return False;           /* invalid, so fails */
87
    }
88
        /* addr = &rqstp->rq_xprt->xp_raddr; */
89
    addr = svc_getcaller (rqstp->rq_xprt);
90
        /* verify it is AF_INET */
91
    if (addr->sin_family != AF_INET) {          /* no, error */
92
        DPRINTF (("TspTranslateRpcAddr: Not an internet address!!\n"));
93
        setErrno (EAFNOSUPPORT);/* invalid addr family */
94
        return False;
95
    }
96
        /* good address type */
97
    up = (unsigned char *) &addr->sin_addr.s_addr;
98
    DPRINTF (("TspTranslateRpcAddr: Sent by %u.%u.%u.%u port #%u\n",
99
        up[0], up[1], up[2], up[3], htons (addr->sin_port)));
100
    memcpy (opaque, addr, sizeof (struct sockaddr_in));
101
    return True;
102
}
103
 
104
    /*
105
     *  TspValidateAddr - validate a passed in opaque address.
106
     *
107
     *  Checks that the passed in address is in the format
108
     *  expected.
109
     */
110
 
111
    Boolean
112
TspValidateAddr (NET_OPAQUE* opaque, NET_OPAQUE* sender)
113
{
114
    struct sockaddr_in* addr;   /* used as template to extract net info */
115
 
116
    addr = (struct sockaddr_in*) opaque;
117
        /* Verify it is AF_INET. Should check against sender IP address too */
118
    if (addr->sin_family != AF_INET) {
119
        DPRINTF (("TspValidateAddr: Back port invalid: %d\n",
120
            htons (addr->sin_port)));
121
        return False;           /* not valid */
122
    }
123
        /* otherwise, we copy in the IP address, since client may not know it */
124
    addr->sin_addr.s_addr = ((struct sockaddr_in*) sender)->sin_addr.s_addr;
125
    DPRINTF (("TspValidateAddr: Back port is %d\n", htons (addr->sin_port)));
126
    return True;
127
}
128
 
129
    /*
130
     *  TspConnGetIndex - lookup an rpc caller's address as a connection entry.
131
     *
132
     *  Looks up an ip address of a caller to locate the
133
     *  connection index in our connection array.
134
     */
135
 
136
    int
137
TspConnGetIndex (struct svc_req* rqstp)
138
{
139
    int         conn;
140
        /* &rqstp->rq_xprt->xp_raddr; */
141
    struct sockaddr_in *addr = svc_getcaller (rqstp->rq_xprt);
142
 
143
    for (conn = 0; conn < conn_list_cnt; conn++) {
144
        if (!conn_list[conn].in_use)
145
            continue;                   /* not used */
146
 
147
        if (addr->sin_addr.s_addr == ((struct sockaddr_in *)
148
                &conn_list [conn].sender)->sin_addr.s_addr
149
                &&  addr->sin_port == ((struct sockaddr_in *)
150
                &conn_list[conn].sender)->sin_port) {
151
            return conn;
152
        }
153
    }
154
    return -1;
155
}
156
 
157
 
158
    /*
159
     *  TspSendWaitChange - send wait-change message to clients to
160
     *                      notify change.
161
     */
162
 
163
    void
164
TspSendWaitChange(
165
    int         conn,           /* connection to send to */
166
    BACK_MSG    msg,            /* BMSG type */
167
    UINT16      spec,           /* special information */
168
    PID         pid,            /* pid it refers to */
169
    UINT32      context,        /* additional context for message */
170
    Boolean     force)          /* force into being only message */
171
{
172
    int                 idx;
173
    struct SEND_LIST*   snd_ptr;
174
 
175
    if (force) {
176
            /* force to top, which means others gone */
177
        idx = 0;
178
        conn_list [conn].send_idx = 1;
179
        conn_list[conn].retry = 0;
180
    } else {
181
        for (idx = 0; idx < (int) conn_list[conn].send_idx; idx++) {
182
            if (conn_list[conn].send_list[idx].send_type == msg
183
                &&  conn_list[conn].send_list[idx].pid == pid)
184
            return;                     /* already pended for this pid */
185
        }
186
        idx = conn_list[conn].send_idx;
187
        if (idx+1 > MAX_SEND)
188
            return;                     /* we lose it, what should we do??? */
189
        conn_list[conn].send_idx++;
190
    }
191
    snd_ptr = &conn_list[conn].send_list[idx];
192
    snd_ptr->send_type = msg;           /* message to send */
193
    snd_ptr->retry = TSP_RETRIES;       /* about 1 minute of retries */
194
    snd_ptr->spec = htons ((u_short) spec);
195
    snd_ptr->pid = htonl (pid);
196
    snd_ptr->context = htonl (context);
197
    TspSendMessage (conn, False);       /* now do the send */
198
}
199
 
200
    /*
201
     *  TspSendMessage - send message at top of send list for connection.
202
     */
203
 
204
    void
205
TspSendMessage( int conn, Boolean resend)
206
{
207
    struct sockaddr_in  addr;
208
    struct UDP_MSG      msg;
209
    int                 cnt;
210
 
211
    if (!resend && conn_list[conn].retry)
212
        return;                 /* already waiting for reply */
213
 
214
        /*
215
         *  Note on above: if no back port we can't remove unless
216
         *  someone blows off.
217
         */
218
    if (!resend) {
219
            /* first time, setup. Set retry count: */
220
        conn_list[conn].retry = conn_list[conn].send_list[0].retry;
221
        conn_list[conn].last_msg_num++; /* new sequence number */
222
        if (!warm_test++) {             /* starting, so enable timer */
223
            alarm (2);                  /* resend every 2 seconds as needed */
224
        }
225
    }
226
 
227
    msg.type    = conn_list[conn].send_list[0].send_type;
228
    msg.msg_num = conn_list[conn].last_msg_num;
229
    msg.spec    = conn_list[conn].send_list[0].spec;
230
    msg.pid     = conn_list[conn].send_list[0].pid;
231
    msg.context = conn_list[conn].send_list[0].context;
232
 
233
    memset (&addr, 0, sizeof addr);
234
    addr.sin_family = AF_INET;
235
    addr.sin_port = ((struct sockaddr_in*)&conn_list[conn].back_port)->sin_port;
236
    addr.sin_addr.s_addr =
237
        ((struct sockaddr_in*)&conn_list[conn].back_port)->sin_addr.s_addr;
238
 
239
    DPRINTF (("TspSendMessage: Sending msg %d (%s) to port %d\n",
240
        msg.type, BmsgNames [msg.type], HL_W (addr.sin_port)));
241
 
242
    cnt = sendto (out_sock, &msg, sizeof msg, 0, (struct sockaddr*) &addr,
243
                    sizeof addr);
244
    if (cnt != sizeof msg) {            /* failed on send */
245
        printf ("%s: Failed to send msg %d to conn %d (%d vs. %d)\n",
246
            ActName, msg.type, conn, cnt, sizeof msg);
247
    }
248
}
249
 
250
    /*
251
     *  TspMessageReceive - confirmation received, now send next if any.
252
     *
253
     *  - since UDP is connectionless, we batch up the sends and use
254
     *    one at a time until we get a message indicating ready for
255
     *    next (from ack).
256
     */
257
 
258
    void
259
TspMessageReceive (int conn, PID pid)
260
{
261
        /* We remove the send list entry and use next if any */
262
    conn_list[conn].retry = 0;   /* reset */
263
    if (!warm_test || !--warm_test) {
264
        alarm (0);                       /* reset timer if not used */
265
    }
266
#ifdef DDEBUG
267
    if (conn_list[conn].send_list[0].send_type == BMSG_WARM) {
268
        DPRINTF (("TspMessageReceive: Connection reset for conn %d\n", conn));
269
    }
270
#endif
271
        /* Move up by one if needed */
272
    if (!--conn_list[conn].send_idx)
273
        return;                 /* no more to do */
274
 
275
    memcpy (conn_list[conn].send_list, conn_list[conn].send_list+1,
276
        conn_list[conn].send_idx * sizeof(struct SEND_LIST)); /* copy down */
277
    TspSendMessage (conn, 0);
278
}
279
 
280
    /*
281
     *  TspGetHostName - return client's host name.
282
     *
283
     *  - this routine returns the name of the client's host or the net
284
     *    number of unknown.
285
     */
286
 
287
    char*
288
TspGetHostName (conn_idx)
289
    int         conn_idx;       /* client connection number */
290
{
291
    static char         buff [30];      /* largest net num */
292
    unsigned char*      cp;
293
 
294
    cp = conn_list[conn_idx].sender.c+4;
295
    sprintf (buff, "%u.%u.%u.%u", cp[0], cp[1], cp[2], cp[3]);
296
    return buff;
297
}
298
 
299
    /*
300
     *  TimeTestHandler - alarm timer handler to resend warm/wait test.
301
     */
302
 
303
    static void
304
TimeTestHandler()
305
{
306
    int         conn;
307
 
308
    if (!warm_test)
309
        return;                 /* no longer enabled */
310
 
311
    for (conn = 0; conn < conn_list_cnt; conn++) {
312
            /* locate all that are using this */
313
        if (!conn_list[conn].in_use)
314
            continue;                   /* not used */
315
 
316
        if (!conn_list[conn].retry) continue;
317
            /* found one that we are testing */
318
        if (!--conn_list[conn].retry) {
319
                /*
320
                 *  Counted down the retries: blow off.
321
                 *  Need to have connection flag to indicate not blowing
322
                 *  off for cases where client is stopped due to being
323
                 *  debugged.
324
                 */
325
            ConnDelete (conn, NULL, CLOSE_IGNORE);
326
            continue;
327
        }
328
        TspSendMessage (conn, True);    /* send another message */
329
    }
330
    alarm (2);                  /* setup for 2 seconds from now */
331
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.