⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 servtsp.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
字号:
/* ************************************************************************** * *  Component:	RDBG *  Module:	servtsp.c * *  Synopsis:	Transport management for remote debug server. * * $Id: servtsp.c,v 1.4.2.1 2003/07/18 05:21:40 ralf Exp $ * ************************************************************************** */#include <sys/errno.h>#include <rdbg/rdbg.h>#include <rdbg/servrpc.h>#include <signal.h>#include <rpc/rpc.h>#include <rpc/svc.h>#include <netinet/in.h>#include <sys/socket.h>static int out_sock;static int warm_test;static void TimeTestHandler ();    /*     *  TspInit - Initialize the transport system.     *     */  voidTspInit (int id){  struct sigaction sa;  struct sockaddr_in addr;  /*   * setup a socket to send event messages back through    */  out_sock = socket (PF_INET, SOCK_DGRAM, 0);  if (out_sock < 0) {    DPRINTF (("TspInit: socket() failed %d errno %d\n",              out_sock, getErrno ()));    return;                     /* failed to open socket, let caller deal with */  }  memset ((void *) (&addr), 0, sizeof (addr));  addr.sin_family = AF_INET;  addr.sin_port = htons (BackPort);  if (bind (out_sock, (struct sockaddr *) &addr, sizeof (addr)) < 0) {    DPRINTF (("TspInit: bind() failed\n"));  }  /*   * setup alarm timer for warm testing    */  memset (&sa, 0, sizeof (sa));  sa.sa_handler = TimeTestHandler;  sigaction (SIGALRM, &sa, 0);}    /*     *  TspTranslateRpcAddr - translate from an RPC handle to an     *                        opaque address.     *     *  Converts the sender's address into the opaque data structure     *  used for network addresses. This is used to look up the sender     *  on each call.     */  BooleanTspTranslateRpcAddr (struct svc_req *rqstp, NET_OPAQUE * opaque){  struct sockaddr_in *addr;     /* used as template to extract net info */  unsigned char *up;  memset (opaque, 0, sizeof (NET_OPAQUE));  /*   *  We interpret the remote address as a standard netbuf name.   *  The format is 2 bytes of address family (normally AF_INET)   *  and then a length (5) and then the IP address.   */  if (rqstp->rq_xprt->xp_addrlen != 16) {    DPRINTF (("TspTranslateRpcAddr: Unknown remote address!!!\n"));    setErrno (EPROTONOSUPPORT);    return False;               /* invalid, so fails */  }  /*   * addr = &rqstp->rq_xprt->xp_raddr;    */  addr = svc_getcaller (rqstp->rq_xprt);  /*   * verify it is AF_INET    */  if (addr->sin_family != AF_INET) {    /* no, error */    DPRINTF (("TspTranslateRpcAddr: Not an internet address!!\n"));    setErrno (EAFNOSUPPORT);    /* invalid addr family */    return False;  }  /*   * good address type    */  up = (unsigned char *) &addr->sin_addr.s_addr;  DPRINTF (("TspTranslateRpcAddr: Sent by %u.%u.%u.%u port #%u\n",            up[0], up[1], up[2], up[3], htons (addr->sin_port)));  memcpy (opaque, addr, sizeof (struct sockaddr_in));  return True;}    /*     *  TspValidateAddr - validate a passed in opaque address.     *     *  Checks that the passed in address is in the format     *  expected.     */  BooleanTspValidateAddr (NET_OPAQUE * opaque, NET_OPAQUE * sender){  struct sockaddr_in *addr;     /* used as template to extract net info */  addr = (struct sockaddr_in *) opaque;  /*   * Verify it is AF_INET. Should check against sender IP address too    */  if (addr->sin_family != AF_INET) {    DPRINTF (("TspValidateAddr: Back port invalid: %d\n",              htons (addr->sin_port)));    return False;               /* not valid */  }  /*   * otherwise, we copy in the IP address, since client may not know it    */  addr->sin_addr.s_addr = ((struct sockaddr_in *) sender)->sin_addr.s_addr;  DPRINTF (("TspValidateAddr: Back port is %d\n", htons (addr->sin_port)));  return True;}    /*     *  TspConnGetIndex - lookup an rpc caller's address as a connection entry.     *     *  Looks up an ip address of a caller to locate the     *  connection index in our connection array.     */  intTspConnGetIndex (struct svc_req *rqstp){  int conn;  /*   * &rqstp->rq_xprt->xp_raddr;    */  struct sockaddr_in *addr = svc_getcaller (rqstp->rq_xprt);  for (conn = 0; conn < conn_list_cnt; conn++) {    if (!conn_list[conn].in_use)      continue;                 /* not used */    if (addr->sin_addr.s_addr == ((struct sockaddr_in *)                                  &conn_list[conn].sender)->sin_addr.s_addr        && addr->sin_port == ((struct sockaddr_in *)                              &conn_list[conn].sender)->sin_port) {      return conn;    }  }  return -1;}    /*     *  TspSendWaitChange - send wait-change message to clients to     *                      notify change.     */  voidTspSendWaitChange (int conn,        /* connection to send to */                   BACK_MSG msg,    /* BMSG type */                   UINT16 spec,     /* special information */                   PID pid,         /* pid it refers to */                   UINT32 context,  /* additional context for message */                   Boolean force)  /* force into being only message */{                                 int idx;  struct SEND_LIST *snd_ptr;  if (force) {    /*     * force to top, which means others gone      */    idx = 0;    conn_list[conn].send_idx = 1;    conn_list[conn].retry = 0;  } else {    for (idx = 0; idx < (int) conn_list[conn].send_idx; idx++) {      if (conn_list[conn].send_list[idx].send_type == msg          && conn_list[conn].send_list[idx].pid == pid)        return;                 /* already pended for this pid */    }    idx = conn_list[conn].send_idx;    if (idx + 1 > MAX_SEND)      return;                   /* we lose it, what should we do??? */    conn_list[conn].send_idx++;  }  snd_ptr = &conn_list[conn].send_list[idx];  snd_ptr->send_type = msg;     /* message to send */  snd_ptr->retry = TSP_RETRIES; /* about 1 minute of retries */  snd_ptr->spec = htons ((u_short) spec);  snd_ptr->pid = htonl (pid);  snd_ptr->context = htonl (context);  TspSendMessage (conn, False); /* now do the send */}    /*     *  TspSendMessage - send message at top of send list for connection.     */  voidTspSendMessage (int conn, Boolean resend){  struct sockaddr_in addr;  struct UDP_MSG msg;  int cnt;  if (!resend && conn_list[conn].retry)    return;                     /* already waiting for reply */  /*   *  Note on above: if no back port we can't remove unless   *  someone blows off.   */  if (!resend) {    /*     * first time, setup. Set retry count:      */    conn_list[conn].retry = conn_list[conn].send_list[0].retry;    conn_list[conn].last_msg_num++; /* new sequence number */    if (!warm_test++) {         /* starting, so enable timer */      alarm (2);                /* resend every 2 seconds as needed */    }  }  msg.type = conn_list[conn].send_list[0].send_type;  msg.msg_num = conn_list[conn].last_msg_num;  msg.spec = conn_list[conn].send_list[0].spec;  msg.pid = conn_list[conn].send_list[0].pid;  msg.context = conn_list[conn].send_list[0].context;  memset (&addr, 0, sizeof (addr));  addr.sin_family = AF_INET;  addr.sin_port =    ((struct sockaddr_in *) &conn_list[conn].back_port)->sin_port;  addr.sin_addr.s_addr =    ((struct sockaddr_in *) &conn_list[conn].back_port)->sin_addr.s_addr;  DPRINTF (("TspSendMessage: Sending msg %d (%s) to port %d\n",            msg.type, BmsgNames[msg.type], HL_W (addr.sin_port)));  cnt = sendto (out_sock, &msg, sizeof (msg), 0, (struct sockaddr *) &addr,                sizeof (addr));  if (cnt != sizeof (msg)) {      /* failed on send */    printf ("%s: Failed to send msg %d to conn %d (%d vs. %ld)\n",            taskName, msg.type, conn, cnt, (long int) sizeof (msg));  }}    /*     *  TspMessageReceive - confirmation received, now send next if any.     *     *  - since UDP is connectionless, we batch up the sends and use     *    one at a time until we get a message indicating ready for     *    next (from ack).     */  voidTspMessageReceive (int conn, PID pid){  /*   * We remove the send list entry and use next if any    */  conn_list[conn].retry = 0;    /* reset */  if (!warm_test || !--warm_test) {    alarm (0);                  /* reset timer if not used */  }#ifdef DDEBUG  if (conn_list[conn].send_list[0].send_type == BMSG_WARM) {    DPRINTF (("TspMessageReceive: Connection reset for conn %d\n", conn));  }#endif  /*   * Move up by one if needed    */  if (!--conn_list[conn].send_idx)    return;                     /* no more to do */  memcpy (conn_list[conn].send_list, conn_list[conn].send_list + 1, conn_list[conn].send_idx * sizeof (struct SEND_LIST));  /* copy down */  TspSendMessage (conn, 0);}    /*     *  TspGetHostName - return client's host name.     *     *  - this routine returns the name of the client's host or the net     *    number of unknown.     */  char *TspGetHostName (conn_idx)     int conn_idx;              /* client connection number */{  static char buff[30];         /* largest net num */  unsigned char *cp;  cp = conn_list[conn_idx].sender.c + 4;  sprintf (buff, "%u.%u.%u.%u", cp[0], cp[1], cp[2], cp[3]);  return buff;}    /*     *  TimeTestHandler - alarm timer handler to resend warm/wait test.     */  static voidTimeTestHandler (){  int conn;  if (!warm_test)    return;                     /* no longer enabled */  for (conn = 0; conn < conn_list_cnt; conn++) {    /*     * locate all that are using this      */    if (!conn_list[conn].in_use)      continue;                 /* not used */    if (!conn_list[conn].retry)      continue;    /*     * found one that we are testing      */    if (!--conn_list[conn].retry) {      /*       *  Counted down the retries: blow off.       *  Need to have connection flag to indicate not blowing       *  off for cases where client is stopped due to being       *  debugged.       */      ConnDelete (conn, NULL, CLOSE_IGNORE);      continue;    }    TspSendMessage (conn, True);    /* send another message */  }  alarm (2);                    /* setup for 2 seconds from now */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -