int udpioRecv(UDPIO *up, char *buf, int buflen) { LOGIO *lp; int error, got; INT32 width; fd_set fds; static int len = sizeof(struct sockaddr_in); static char *fid = "udpioRecv"; if (up == NULL || buf == NULL) { errno = EINVAL; lp = (up == NULL) ? NULL : up->lp; logioMsg(lp, LOG_ERR, "%s: NULL input not allowed", fid); return -1; } if (buflen < 1) { logioMsg(up->lp, LOG_ERR, "%s: illegal buflen '%d'", fid, buflen); return -1; } if (up->sd == INVALID_SOCKET) { logioMsg(up->lp, LOG_ERR, "%s: invalid socket", fid, buflen); errno = EINVAL; return -1; } width = getdtablesize(); FD_ZERO(&fds); FD_SET(up->sd, &fds); got = 0; while (got == 0) { error = select(width, &fds, NULL, NULL, &up->to); if (error > 0) { got = RECVFROM(up->sd, buf, buflen, 0, &up->peer.addr, &len); if (got > 0) { inet_ntop(AF_INET, &up->peer.addr, up->peer.ident, MAXPATHLEN); } else { logioMsg(up->lp, LOG_INFO, "%s: RECVFROM: %s", fid, strerror(errno)); if (errno != EAGAIN && errno != EINTR) return -1; } } else if (error == 0) { errno = ETIMEDOUT; return 0; } else if (errno != EAGAIN && errno != EINTR) { logioMsg(up->lp, LOG_INFO, "%s: select: %s", fid, strerror(errno)); return -1; } } UpdateStats(&up->stats.recv, got, utilTimeStamp()); return got; }
static int _recv_request(struct mls_elope *elope, struct mls_elope_packet **reqp) { int ret = 0; unsigned char* req = _req; int len = sizeof(_req); elope->from_len = sizeof(elope->from); len = RECVFROM(elope->srv->sock, req, len, 0, (struct sockaddr*)&(elope->from), &(elope->from_len)); if (len < 0) { ret = -errno; LOG_ERR(MLS_LOG_DEFAULT_MODULE, "recvfrom(%d): %s.\n", errno, strerror(errno)); goto out; } *reqp = (struct mls_elope_packet*)req; /* check packet (length) */ if (len < MLS_ELOPE_PACKET_HEADER_LENGTH) { LOG_ERR(MLS_LOG_DEFAULT_MODULE, "invalid packet length = %d", len); ret = -1; goto out; } switch((*reqp)->svc) { default: LOG_ERR(MLS_LOG_DEFAULT_MODULE, "invalid packet svc = %d", (*reqp)->svc); ret = -1; goto out; /* Request */ case MLS_ELOPE_SVC_SET_REQ: case MLS_ELOPE_SVC_GET_REQ: break; } out: return ret; }
//------------------------------------------------------------------------------ // // Receive() - Attempts to receive a block of data on an established // connection. Data is received in an internal buffer managed // by the class. This buffer is only valid until the next call // to Receive(), a call to Close(), or until the object goes out // of scope. // //------------------------------------------------------------------------------ i32 TDSocket::Receive(i32 nMaxBytes) { m_nBytesReceived = 0; //-------------------------------------------------------------------------- // If the socket is invalid then return false. //-------------------------------------------------------------------------- if (IsSocketValid() == false) { return m_nBytesReceived; } //-------------------------------------------------------------------------- // Free existing buffer and allocate a new buffer the size of // nMaxBytes. //-------------------------------------------------------------------------- if (nMaxBytes != m_nBufferSize) { m_nBufferSize = nMaxBytes; m_pBuffer.clear(); m_pBuffer.resize(m_nBufferSize); } SetSocketError(SocketSuccess); switch (m_nSocketType) { //---------------------------------------------------------------------- // If zero bytes are received, then return. If SocketERROR is // received, free buffer and return CSocket::SocketError (-1) to caller. //---------------------------------------------------------------------- case TDSocket::SocketTypeTcp: { do { m_nBytesReceived = RECV(m_socket, &m_pBuffer[m_nBytesReceived], nMaxBytes - m_nBytesReceived, m_nFlags); TranslateSocketError(); } while (IsSocketValid() && (GetSocketError() == TDSocket::SocketInterrupted)); break; } case TDSocket::SocketTypeUdp: { socklen_t srcSize; srcSize = sizeof(struct sockaddr_in); if (GetMulticast() == true) { do { m_nBytesReceived = RECVFROM(m_socket, &m_pBuffer[0], nMaxBytes, 0, &m_stMulticastGroup, &srcSize); TranslateSocketError(); } while (IsSocketValid() && GetSocketError() == TDSocket::SocketInterrupted); } else { do { m_nBytesReceived = RECVFROM(m_socket, &m_pBuffer[0], nMaxBytes, 0, &m_stClientSockaddr, &srcSize); TranslateSocketError(); } while (GetSocketError() == TDSocket::SocketInterrupted); } break; } default: break; } TranslateSocketError(); return m_nBytesReceived; }
//------------------------------------------------------------------------------ // // Receive() - Attempts to receive a block of data on an established // connection. Data is received in an internal buffer managed // by the class. This buffer is only valid until the next call // to Receive(), a call to Close(), or until the object goes out // of scope. // //------------------------------------------------------------------------------ int32 CSimpleSocket::Receive(int32 nMaxBytes) { m_nBytesReceived = 0; //-------------------------------------------------------------------------- // If the socket is invalid then return false. //-------------------------------------------------------------------------- if (IsSocketValid() == false) { return m_nBytesReceived; } //-------------------------------------------------------------------------- // Free existing buffer and allocate a new buffer the size of // nMaxBytes. //-------------------------------------------------------------------------- if ((m_pBuffer != NULL) && (nMaxBytes != m_nBufferSize)) { delete [] m_pBuffer; m_pBuffer = NULL; } //-------------------------------------------------------------------------- // Allocate a new internal buffer to receive data. //-------------------------------------------------------------------------- if (m_pBuffer == NULL) { m_nBufferSize = nMaxBytes; m_pBuffer = new uint8[nMaxBytes]; } SetSocketError(SocketSuccess); switch (m_nSocketType) { m_timer.Initialize(); m_timer.SetStartTime(); //---------------------------------------------------------------------- // If zero bytes are received, then return. If SocketERROR is // received, free buffer and return CSocket::SocketError (-1) to caller. //---------------------------------------------------------------------- case CSimpleSocket::SocketTypeTcp: { do { m_nBytesReceived = RECV(m_socket, (m_pBuffer + m_nBytesReceived), nMaxBytes, m_nFlags); TranslateSocketError(); } while ((GetSocketError() == CSimpleSocket::SocketInterrupted)); break; } case CSimpleSocket::SocketTypeUdp: { uint32 srcSize; srcSize = sizeof(struct sockaddr_in); if (GetMulticast() == true) { do { m_nBytesReceived = RECVFROM(m_socket, m_pBuffer, nMaxBytes, 0, &m_stMulticastGroup, &srcSize); TranslateSocketError(); } while (GetSocketError() == CSimpleSocket::SocketInterrupted); } else { do { m_nBytesReceived = RECVFROM(m_socket, m_pBuffer, nMaxBytes, 0, &m_stClientSockaddr, &srcSize); TranslateSocketError(); } while (GetSocketError() == CSimpleSocket::SocketInterrupted); } break; } default: break; } m_timer.SetEndTime(); TranslateSocketError(); //-------------------------------------------------------------------------- // If we encounter an error translate the error code and return. One // possible error code could be EAGAIN (EWOULDBLOCK) if the socket is // non-blocking. This does not mean there is an error, but no data is // yet available on the socket. //-------------------------------------------------------------------------- if (m_nBytesReceived == CSimpleSocket::SocketError) { if (m_pBuffer != NULL) { delete [] m_pBuffer; m_pBuffer = NULL; } } return m_nBytesReceived; }
int mls_elope_rpc(struct mls_net_ud_cln *cln, struct mls_elope_packet *req, struct mls_elope_packet *res, int reslen) { int ret = 0; int sock = cln->sock; struct sockaddr_storage from; socklen_t fromlen; ssize_t len; fd_set mask; int width; int i, retry = 2, wait_sec = 2; FD_ZERO(&mask); FD_SET(sock, &mask); width = sock + 1; for (i = 0; i < retry; i++) { fd_set ready; struct timeval timeout; /* request */ if ((len = SENDTO(sock, req, mls_elope_packet_get_length(req), 0, (struct sockaddr *)&(cln->to), cln->tolen)) == -1) { ret = -errno; LOG_ERR(MLS_LOG_DEFAULT_MODULE, "sendto(%d): %s.\n", errno, strerror(errno)); goto out; } ready = mask; timeout.tv_sec = wait_sec; timeout.tv_usec = 0; switch (select(width, (fd_set*)&ready, NULL, NULL, &timeout)) { case -1: ret = -errno; LOG_ERR(MLS_LOG_DEFAULT_MODULE, "select(%d,%s)\n", errno, strerror(errno)); goto out; case 0: /* timeout, retry */ break; default: if (FD_ISSET(sock, &ready)) { ssize_t len; /* response */ fromlen = sizeof(from); if ((len = RECVFROM(sock, (char*)res, reslen, 0, (struct sockaddr*)&from, &fromlen)) == -1) { ret = -errno; LOG_ERR(MLS_LOG_DEFAULT_MODULE, "recvfrom(%d): %s.\n", errno, strerror(errno)); goto out; } /* OK, response packet */ ret = len; LOG_INFO(MLS_LOG_DEFAULT_MODULE, "message rpc, ok(%d,%d)\n", i, ret); goto out; } break; } } /* retry over */ ret = -1; LOG_ERR(MLS_LOG_DEFAULT_MODULE, "message rpc, retry over(%d,%d)\n", i, ret); out: return ret; }
int send_mesg2gtmsecshr(unsigned int code, unsigned int id, char *path, int path_len) { int client_sockfd, create_server_status, fcntl_res; int req_code, wait_count = 0; int recv_len, send_len; ssize_t num_chars_recvd, num_chars_sent; int save_errno, ret_code = 0, init_ret_code = 0; int loop_count = 0; int recv_complete, send_complete; boolean_t retry = FALSE; size_t server_proc_len; int semop_res; int selstat, status; char *recv_ptr, *send_ptr; struct sockaddr_un server_proc; struct sembuf sop[4]; fd_set wait_on_fd; gtmsecshr_mesg mesg; TID timer_id; int4 msec_timeout; char *gtm_tmp_ptr; struct stat stat_buf; struct shmid_ds shm_info; int len; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; DBGGSSHR((LOGFLAGS, "secshr_client: New send request\n")); if (!gtm_dist_ok_to_use) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_GTMDISTUNVERIF, 4, STRLEN(gtm_dist), gtm_dist, gtmImageNames[image_type].imageNameLen, gtmImageNames[image_type].imageName); /* Create communication key (hash of release name) if it has not already been done */ if (0 == TREF(gtmsecshr_comkey)) { STR_HASH((char *)gtm_release_name, gtm_release_name_len, TREF(gtmsecshr_comkey), 0); } timer_id = (TID)send_mesg2gtmsecshr; if (!gtmsecshr_file_check_done) { len = STRLEN(gtm_dist); memcpy(gtmsecshr_path, gtm_dist, len); gtmsecshr_path[len] = '/'; memcpy(gtmsecshr_path + len + 1, GTMSECSHR_EXECUTABLE, STRLEN(GTMSECSHR_EXECUTABLE)); gtmsecshr_pathname.addr = gtmsecshr_path; gtmsecshr_pathname.len = len + 1 + STRLEN(GTMSECSHR_EXECUTABLE); assertpro(GTM_PATH_MAX > gtmsecshr_pathname.len); gtmsecshr_pathname.addr[gtmsecshr_pathname.len] = '\0'; if (-1 == Stat(gtmsecshr_pathname.addr, &stat_buf)) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, LEN_AND_LIT("stat"), CALLFROM, errno); if ((ROOTUID != stat_buf.st_uid) || !(stat_buf.st_mode & S_ISUID) || (0 != ACCESS(gtmsecshr_pathname.addr, (X_OK)))) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_GTMSECSHRPERM); gtmsecshr_file_check_done = TRUE; } if (!gtmsecshr_sock_init_done && (0 < (init_ret_code = gtmsecshr_sock_init(CLIENT)))) /* Note assignment */ return init_ret_code; DEBUG_ONLY(mesg.usesecshr = TREF(gtm_usesecshr)); /* Flag ignored in PRO build */ while (MAX_COMM_ATTEMPTS >= loop_count) { /* first, try the sendto */ req_code = mesg.code = code; send_len = (int4)(GTM_MESG_HDR_SIZE); if (REMOVE_FILE == code) { assert(GTM_PATH_MAX > path_len); /* Name is not user supplied so simple check */ memcpy(mesg.mesg.path, path, path_len); send_len += path_len; } else if (FLUSH_DB_IPCS_INFO == code) { assert(GTM_PATH_MAX > db_ipcs.fn_len); memcpy(&mesg.mesg.db_ipcs, &db_ipcs, (offsetof(ipcs_mesg, fn[0]) + db_ipcs.fn_len + 1)); /* Most of the time file length is much smaller than GTM_PATH_MAX */ send_len += offsetof(ipcs_mesg, fn[0]); send_len += mesg.mesg.db_ipcs.fn_len + 1; } else { mesg.mesg.id = id; send_len += SIZEOF(mesg.mesg.id); } DBGGSSHR((LOGFLAGS, "secshr_client: loop %d frm-pid: %d to-pid: %d send_len: %d code: %d\n", loop_count, process_id, id, send_len, code)); mesg.comkey = TREF(gtmsecshr_comkey); /* Version communication key */ mesg.pid = process_id; /* Process id of client */ mesg.seqno = ++cur_seqno; send_ptr = (char *)&mesg; send_complete = FALSE; SENDTO_SOCK(gtmsecshr_sockfd, send_ptr, send_len, 0, (struct sockaddr *)>msecshr_sock_name, (GTM_SOCKLEN_TYPE)gtmsecshr_sockpath_len, num_chars_sent); /* This form handles EINTR internally */ save_errno = errno; DBGGSSHR((LOGFLAGS, "secshr_client: sendto rc: %d errno: %d (only important if rc=-1)\n", (int)num_chars_sent, save_errno)); if (0 >= num_chars_sent) { /* SENDTO_SOCK failed - start server and attempt to resend */ if ((EISCONN == save_errno) || (EBADF == save_errno)) { gtmsecshr_sock_cleanup(CLIENT); gtmsecshr_sock_init(CLIENT); wcs_backoff(loop_count + 1); DBGGSSHR((LOGFLAGS, "secshr_client: Connection error, reset socket\n")); } else { if (0 < loop_count) /* No message unless attempted server start at least once */ send_msg_csa(CSA_ARG(NULL) VARLSTCNT(11) ERR_GTMSECSHRSRVF, 4, RTS_ERROR_TEXT("Client"), process_id, loop_count - 1, ERR_TEXT, 2, RTS_ERROR_TEXT("sendto to gtmsecshr failed"), save_errno); START_SERVER; DBGGSSHR((LOGFLAGS, "secshr_client: sendto() failed - restarting server\n")); } loop_count++; continue; } SETUP_FOR_RECV; /* Sets timer, recvcomplete = FALSE */ do { /* Note RECVFROM does not loop on EINTR return codes so must be handled. Note also we only expect * to receive the message header back as an acknowledgement. */ num_chars_recvd = RECVFROM(gtmsecshr_sockfd, recv_ptr, GTM_MESG_HDR_SIZE, 0, (struct sockaddr *)0, (GTM_SOCKLEN_TYPE *)0); save_errno = errno; DBGGSSHR((LOGFLAGS, "secshr_client: recvfrom rc: %d errno: %d (only important if rc=-1)\n", (int)num_chars_recvd, save_errno)); if (0 <= num_chars_recvd) { /* Message received - make sure it is large enough to have set seqno before we do anything * to rely on it. */ if ((GTM_MESG_HDR_SIZE <= num_chars_recvd) && (mesg.seqno == cur_seqno) && (TREF(gtmsecshr_comkey) == mesg.comkey)) recv_complete = TRUE; else { /* Message too short or not correct sequence */ cancel_timer(timer_id); /* Print True/False for the possibilities we failed */ DBGGSSHR((LOGFLAGS, "secshr_client: Message incorrect - chars: %d, seq: %d\n", (GTM_MESG_HDR_SIZE <= num_chars_recvd), (mesg.seqno == cur_seqno))); SETUP_FOR_RECV; continue; } } else { /* Something untoward happened */ if (client_timer_popped) break; if (EINTR == save_errno) /* Had an irrelevant interrupt - ignore */ continue; if (EBADF == save_errno) break; send_msg_csa(CSA_ARG(NULL) VARLSTCNT(11) ERR_GTMSECSHRSRVF, 4, RTS_ERROR_TEXT("Client"), process_id, loop_count - 1, ERR_TEXT, 2, RTS_ERROR_TEXT("recvfrom from gtmsecshr failed"), save_errno); if ((ECONNRESET == save_errno) || (ENOTCONN == save_errno)) { num_chars_recvd = 0; break; } gtmsecshr_sock_cleanup(CLIENT); return save_errno; } } while (!recv_complete); cancel_timer(timer_id); if (client_timer_popped || (EBADF == save_errno) || (0 == num_chars_recvd)) { /* Timeout, connection issues, bad descriptor block - retry */ gtmsecshr_sock_cleanup(CLIENT); gtmsecshr_sock_init(CLIENT); retry = TRUE; if (client_timer_popped) { START_SERVER; DBGGSSHR((LOGFLAGS, "secshr_client: Read timer popped - restarting server\n")); } else DBGGSSHR((LOGFLAGS, "secshr_client: Read error - socket reset, retrying\n")); loop_count++; continue; } /* Response to *our* latest message available */ assert(recv_complete); if (ret_code = mesg.code) /* Warning - assignment */ { DBGGSSHR((LOGFLAGS, "secshr_client: non-zero response from gtmsecshr - request: %d retcode: %d\n", req_code, ret_code)); if (INVALID_COMKEY == ret_code) { /* Comkey mismatch means for a different version of GT.M - we will not handle it */ send_msg_csa(CSA_ARG(NULL) VARLSTCNT(13) ERR_GTMSECSHRSRVFIL, 7, RTS_ERROR_TEXT("Client"), process_id, mesg.pid, req_code, RTS_ERROR_TEXT(mesg.mesg.path), ERR_TEXT, 2, RTS_ERROR_STRING("Communicating with wrong GT.M version")); rts_error_csa(CSA_ARG(NULL) VARLSTCNT(13) ERR_GTMSECSHRSRVFIL, 7, RTS_ERROR_TEXT("Client"), process_id, mesg.pid, req_code, RTS_ERROR_TEXT(mesg.mesg.path), ERR_TEXT, 2, RTS_ERROR_STRING("Communicating with wrong GT.M version")); break; /* rts_error should not return */ } switch(req_code) { case REMOVE_FILE: /* Called from mutex_sock_init(). Path (and length) contain null terminator byte. * See if file still exists (may have been deleted by earlier attempt). Caller * handles actual error. */ if ((-1 != Stat(path, &stat_buf)) || (ENOENT != ret_code)) send_msg_csa(CSA_ARG(NULL) VARLSTCNT(14) ERR_GTMSECSHRSRVFIL, 7, RTS_ERROR_TEXT("Client"), process_id, mesg.pid, req_code, RTS_ERROR_TEXT(mesg.mesg.path), ERR_TEXT, 2, RTS_ERROR_STRING(secshr_fail_mesg_code[req_code]), mesg.code); else ret_code = 0; /* File is gone so this or a previous try actually worked */ break; case REMOVE_SEM: /* See if semaphore still eixsts (may have been removed by earlier attempt that * got a reply confused or lost). If not there, no error. Else error to op-log. */ if ((-1 != semctl(id, 0, GETVAL)) && !SEM_REMOVED(errno)) send_msg_csa(CSA_ARG(NULL) VARLSTCNT(13) ERR_GTMSECSHRSRVFID, 6, RTS_ERROR_TEXT("Client"), process_id, mesg.pid, req_code, mesg.mesg.id, ERR_TEXT, 2, RTS_ERROR_STRING(secshr_fail_mesg_code[req_code]), mesg.code); else ret_code = 0; /* File is gone so this or a previous try actually worked */ case REMOVE_SHM: /* See if shmem still eixsts (may have been removed by earlier attempt that * got a reply confused or lost). If not there, no error. Else error to op-log. * Note - */ if ((-1 != shmctl(id, IPC_STAT, &shm_info)) && !SEM_REMOVED(errno)) send_msg_csa(CSA_ARG(NULL) VARLSTCNT(13) ERR_GTMSECSHRSRVFID, 6, RTS_ERROR_TEXT("Client"), process_id, mesg.pid, req_code, mesg.mesg.id, ERR_TEXT, 2, RTS_ERROR_STRING(secshr_fail_mesg_code[req_code]), mesg.code); else ret_code = 0; /* File is gone so this or a previous try actually worked */ break; case FLUSH_DB_IPCS_INFO: /* Errors handled by caller */ break; default: if (EPERM != mesg.code && EACCES != mesg.code) send_msg_csa(CSA_ARG(NULL) VARLSTCNT(13) ERR_GTMSECSHRSRVFID, 6, RTS_ERROR_TEXT("Client"), process_id, mesg.pid, req_code, mesg.mesg.id, ERR_TEXT, 2, RTS_ERROR_STRING(secshr_fail_mesg_code[req_code]), mesg.code); break; } } break; } if (MAX_COMM_ATTEMPTS < loop_count) { ret_code = -1; gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(10) ERR_GTMSECSHRSRVF, 4, RTS_ERROR_TEXT("Client"), process_id, loop_count - 1, ERR_TEXT, 2, RTS_ERROR_TEXT("Unable to communicate with gtmsecshr")); /* If gtm_tmp is not defined, show default path */ if (gtm_tmp_ptr = GETENV("gtm_tmp")) send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_GTMSECSHRTMPPATH, 2, RTS_ERROR_TEXT(gtm_tmp_ptr), ERR_TEXT, 2, RTS_ERROR_TEXT("(from $gtm_tmp)")); else send_msg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_GTMSECSHRTMPPATH, 2, RTS_ERROR_TEXT("/tmp")); } if (ONETIMESOCKET == init_ret_code) gtmsecshr_sock_cleanup(CLIENT); return ret_code; }