Diff for /libaitrpc/src/aitrpc.c between versions 1.9 and 1.16

version 1.9, 2013/04/02 15:50:14 version 1.16, 2015/01/15 01:42:37
Line 12  terms: Line 12  terms:
 All of the documentation and software included in the ELWIX and AITNET  All of the documentation and software included in the ELWIX and AITNET
 Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>  Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013Copyright 2004 - 2014
         by Michael Pounov <misho@elwix.org>.  All rights reserved.          by Michael Pounov <misho@elwix.org>.  All rights reserved.
   
 Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
Line 73  AVL_GENERATE(tagRPCFuncs, tagRPCFunc, func_node, rpc_f Line 73  AVL_GENERATE(tagRPCFuncs, tagRPCFunc, func_node, rpc_f
 #pragma GCC visibility pop  #pragma GCC visibility pop
   
 // rpc_GetErrno() Get error code of last operation  // rpc_GetErrno() Get error code of last operation
inline intint
 rpc_GetErrno()  rpc_GetErrno()
 {  {
         return rpc_Errno;          return rpc_Errno;
 }  }
   
 // rpc_GetError() Get error text of last operation  // rpc_GetError() Get error text of last operation
inline const char *const char *
 rpc_GetError()  rpc_GetError()
 {  {
         return rpc_Error;          return rpc_Error;
 }  }
   
 // rpc_SetErr() Set error to variables for internal use!!!  // rpc_SetErr() Set error to variables for internal use!!!
inline voidvoid
 rpc_SetErr(int eno, char *estr, ...)  rpc_SetErr(int eno, char *estr, ...)
 {  {
         va_list lst;          va_list lst;
Line 107  rpc_SetErr(int eno, char *estr, ...) Line 107  rpc_SetErr(int eno, char *estr, ...)
  * @s = active session   * @s = active session
  * return: -1, 1, 2, 3 are errors or 0 ok   * return: -1, 1, 2, 3 are errors or 0 ok
  */   */
inline intint
 rpc_chkPktSession(rpc_sess_t *p, rpc_sess_t *s)  rpc_chkPktSession(rpc_sess_t *p, rpc_sess_t *s)
 {  {
         if (!p || !s)          if (!p || !s)
Line 128  rpc_chkPktSession(rpc_sess_t *p, rpc_sess_t *s) Line 128  rpc_chkPktSession(rpc_sess_t *p, rpc_sess_t *s)
  * @s = host session   * @s = host session
  * return: -1 error or 0 ok   * return: -1 error or 0 ok
  */   */
inline intint
 rpc_addPktSession(rpc_sess_t *p, rpc_sess_t *s)  rpc_addPktSession(rpc_sess_t *p, rpc_sess_t *s)
 {  {
         if (!p || !s)          if (!p || !s)
Line 138  rpc_addPktSession(rpc_sess_t *p, rpc_sess_t *s) Line 138  rpc_addPktSession(rpc_sess_t *p, rpc_sess_t *s)
         p->sess_instance = s->sess_instance;          p->sess_instance = s->sess_instance;
   
         return 0;          return 0;
   }
   
   /*
    * rpc_Read() - RPC read operation
    *
    * @sock = socket
    * @type = type of socket
    * @flags = receive flags
    * @sa = check client address, if you use udp protocol
    * @buf = buffer
    * @blen = buffer length
    * return: -1 error, 0 EOF or or >0 readed bytes into buffer
    */
   ssize_t
   rpc_Read(int sock, int type, int flags, sockaddr_t * __restrict sa, 
                   u_char * __restrict buf, size_t blen)
   {
           struct pollfd pfd;
           sockaddr_t sa2;
           socklen_t salen;
           int ret = 0, len, cx = 0;
           ait_val_t v = AIT_VAL_INIT;
           struct ether_header *eh;
           struct bpf_hdr *h;
           ether_addr_t bcst = {{ [0 ... sizeof bcst - 1] = 0xff }};
   
           if (type == SOCK_BPF && sa) {
                   AIT_SET_BUF(&v, NULL, blen);
                   h = (struct bpf_hdr*) AIT_GET_BUF(&v);
           }
   
           pfd.fd = sock;
           pfd.events = POLLIN | POLLPRI;
           memset(buf, 0, blen);
           memset(&sa2, 0, sizeof sa2);
           salen = sa2.ss.ss_len = sizeof(sockaddr_t);
   
           for (len = blen; len > 0; len -= ret, buf += ret) {
                   if ((ret = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) < 1 || 
                                   pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
                           if (ret)
                                   LOGERR;
                           else
                                   rpc_SetErr(ETIMEDOUT, "Timeout reached! Server not respond");
                           if (type == SOCK_BPF)
                                   AIT_FREE_VAL(&v);
                           return -1;
                   }
                   if (type == SOCK_STREAM)
                           ret = recv(sock, buf, len, flags);
                   else if (type == SOCK_BPF && sa) {
                           ret = read(sock, AIT_GET_BUF(&v), AIT_LEN(&v));
                           if (ret > 0) {
                                   ret -= h->bh_hdrlen;
                                   if (ret < h->bh_caplen || h->bh_caplen != h->bh_datalen || 
                                                   ret < ETHER_HDR_LEN + sizeof(struct tagRPCCall)) {
                                           if (cx < 3) {
                                                   cx++;
                                                   ret ^= ret;
                                                   continue;       /* wait for known address */
                                           } else {
                                                   AIT_FREE_VAL(&v);
                                                   return -1;
                                           }
                                   }
                                   ret = h->bh_caplen;
                                   eh = (struct ether_header*) (AIT_GET_BUF(&v) + h->bh_hdrlen);
                                   ret -= ETHER_HDR_LEN;
                                   if (eh->ether_type != ntohs(RPC_DEFPORT)) {
                                           if (cx < 3) {
                                                   cx++;
                                                   ret ^= ret;
                                                   continue;       /* wait for known address */
                                           } else {
                                                   AIT_FREE_VAL(&v);
                                                   return -1;
                                           }
                                   }
   #if 0
                                   else
                                           e_getlinkbymac((const ether_addr_t*) eh->ether_shost, &sa2);
                                   if (sa && e_addrcmp(sa, &sa2, 0)) {
   #else
                                   if (!memcmp(bcst.octet, eh->ether_dhost, sizeof bcst) || 
                                                   !memcmp(bcst.octet, eh->ether_shost, sizeof bcst)) {
   #endif
                                           if (cx < 3) {
                                                   cx++;
                                                   ret ^= ret;
                                                   continue;       /* wait for known address */
                                           } else {
                                                   AIT_FREE_VAL(&v);
                                                   return -1;
                                           }
                                   }
                                   memcpy(buf, (u_char*) (eh + 1), MIN(ret, len));
                                   AIT_FREE_VAL(&v);
                                   return ret;
                           }
                   } else {
                           ret = recvfrom(sock, buf, len, flags, &sa2.sa, &salen);
                           if (ret > -1 && sa && e_addrcmp(sa, &sa2, 42)) {
                                   ret ^= ret;
                                   continue;       /* wait for known address */
                           }
                   }
                   if (ret == -1) {
                           LOGERR;
                           if (type == SOCK_BPF)
                                   AIT_FREE_VAL(&v);
                           return -1;
                   }
                   if (!ret) {     /* EOF */
                           if (type == SOCK_BPF)
                                   AIT_FREE_VAL(&v);
                           return 0;
                   }
           }
           ret = blen - len;
   
           if (type == SOCK_BPF)
                   AIT_FREE_VAL(&v);
           return ret;
   }
   
   /*
    * rpc_Write() - RPC write operation
    *
    * @sock = socket
    * @type = type of socket
    * @flags = send flags
    * @sa = send to client address, if you use udp protocol
    * @buf = buffer
    * @blen = buffer length
    * return: -1 error, 0 EOF or >0 written bytes into buffer
    */
   ssize_t
   rpc_Write(int sock, int type, int flags, sockaddr_t * __restrict sa, 
                   u_char * __restrict buf, size_t blen)
   {
           struct pollfd pfd;
           int ret = 0, len = 0;
           ait_val_t v = AIT_VAL_INIT;
           struct ether_header *eh;
   
           if (type == SOCK_BPF && sa) {
                   AIT_SET_BUF(&v, NULL, blen + sizeof(struct ether_header));
                   eh = (struct ether_header*) AIT_GET_BUF(&v);
                   memcpy(eh->ether_dhost, LLADDR(&sa->sdl), ETHER_ADDR_LEN);
                   eh->ether_type = htons(RPC_DEFPORT);
                   memcpy(eh + 1, buf, blen);
                   blen += sizeof(struct ether_header);
           }
   
           pfd.fd = sock;
           pfd.events = POLLOUT;
           for (len = blen; len > 0; len -= ret, buf += ret) {
                   if ((ret = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) < 1 || 
                                   pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
   #if 0
                           if (!ret)
                                   continue;
   #endif
                           if (ret > 0)
                                   rpc_SetErr(EPIPE, "Disconnected RPC session\n");
                           else
                                   LOGERR;
                           if (type == SOCK_BPF)
                                   AIT_FREE_VAL(&v);
                           return -1;
                   }
                   if (type == SOCK_STREAM)
                           ret = send(sock, buf, len, flags);
                   else if (type == SOCK_BPF && sa) {
                           ret = write(sock, AIT_GET_BUF(&v), AIT_LEN(&v));
                   } else if (sa)
                           ret = sendto(sock, buf, len, flags, &sa->sa, sa->sa.sa_len);
                   else {
                           rpc_SetErr(EINVAL, "Invalid argument(s)!");
                           if (type == SOCK_BPF)
                                   AIT_FREE_VAL(&v);
                           return -1;
                   }
                   if (ret == -1) {
                           LOGERR;
                           if (type == SOCK_BPF)
                                   AIT_FREE_VAL(&v);
                           return -1;
                   }
                   if (!ret) {     /* EOF */
                           if (type == SOCK_BPF)
                                   AIT_FREE_VAL(&v);
                           return 0;
                   }
           }
           ret = blen - len;
           if (ret != blen) {
                   rpc_SetErr(EPROCUNAVAIL, "RPC request, should be send %d bytes, "
                                   "really sended %d bytes", blen, ret);
                   if (type == SOCK_BPF)
                           AIT_FREE_VAL(&v);
                   return -1;
           }
   
           if (type == SOCK_BPF)
                   AIT_FREE_VAL(&v);
           return ret;
 }  }

Removed from v.1.9  
changed lines
  Added in v.1.16


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>