/* * makeSocket() */ static bool makeSocket ( unsigned short port, bool reuseAddr, SOCKET * pSock ) { int status; union { struct sockaddr_in ia; struct sockaddr sa; } bd; SOCKET sock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, 0 ); if ( sock == INVALID_SOCKET ) { return false; } /* * no need to bind if unconstrained */ if ( port != PORT_ANY ) { memset ( (char *) &bd, 0, sizeof (bd) ); bd.ia.sin_family = AF_INET; bd.ia.sin_addr.s_addr = htonl ( INADDR_ANY ); bd.ia.sin_port = htons ( port ); status = bind ( sock, &bd.sa, (int) sizeof(bd) ); if ( status < 0 ) { epicsSocketDestroy ( sock ); return false; } if ( reuseAddr ) { epicsSocketEnableAddressReuseDuringTimeWaitState ( sock ); } } *pSock = sock; return true; }
/* * logClientMakeSock () */ static void logClientMakeSock (logClient *pClient) { # ifdef DEBUG fprintf (stderr, "log client: creating socket..."); # endif epicsMutexMustLock (pClient->mutex); /* * allocate a socket */ pClient->sock = epicsSocketCreate ( AF_INET, SOCK_STREAM, 0 ); if ( pClient->sock == INVALID_SOCKET ) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf ( stderr, "log client: no socket error %s\n", sockErrBuf ); } epicsMutexUnlock (pClient->mutex); # ifdef DEBUG fprintf (stderr, "done\n"); # endif }
int E2050Reboot(char * inetAddr) { struct sockaddr_in serverAddr; SOCKET fd; int status; int nbytes; errno = 0; fd = epicsSocketCreate(PF_INET, SOCK_STREAM, 0); if(fd == -1) { printf("can't create socket %s\n",strerror(errno)); return(-1); } memset((char*)&serverAddr, 0, sizeof(struct sockaddr_in)); serverAddr.sin_family = PF_INET; /* 23 is telnet port */ status = aToIPAddr(inetAddr,23,&serverAddr); if(status) { printf("aToIPAddr failed\n"); return(-1); } errno = 0; status = connect(fd,(struct sockaddr*)&serverAddr, sizeof(serverAddr)); if(status) { printf("can't connect %s\n",strerror (errno)); epicsSocketDestroy(fd); return(-1); } nbytes = send(fd,"reboot\ny\n",9,0); if(nbytes!=9) printf("nbytes %d expected 9\n",nbytes); epicsSocketDestroy(fd); epicsThreadSleep(20.0); return(0); }
/** * Load configuration. */ void ServerContextImpl::loadConfiguration() { Configuration::shared_pointer config = getConfiguration(); // TODO for now just a simple switch int32 debugLevel = config->getPropertyAsInteger(PVACCESS_DEBUG, 0); if (debugLevel > 0) SET_LOG_LEVEL(logLevelDebug); // TODO multiple addresses _ifaceAddr.ia.sin_family = AF_INET; _ifaceAddr.ia.sin_addr.s_addr = htonl(INADDR_ANY); _ifaceAddr.ia.sin_port = 0; config->getPropertyAsAddress("EPICS_PVAS_INTF_ADDR_LIST", &_ifaceAddr); _beaconAddressList = config->getPropertyAsString("EPICS_PVA_ADDR_LIST", _beaconAddressList); _beaconAddressList = config->getPropertyAsString("EPICS_PVAS_BEACON_ADDR_LIST", _beaconAddressList); _autoBeaconAddressList = config->getPropertyAsBoolean("EPICS_PVA_AUTO_ADDR_LIST", _autoBeaconAddressList); _autoBeaconAddressList = config->getPropertyAsBoolean("EPICS_PVAS_AUTO_BEACON_ADDR_LIST", _autoBeaconAddressList); _beaconPeriod = config->getPropertyAsFloat("EPICS_PVA_BEACON_PERIOD", _beaconPeriod); _beaconPeriod = config->getPropertyAsFloat("EPICS_PVAS_BEACON_PERIOD", _beaconPeriod); _serverPort = config->getPropertyAsInteger("EPICS_PVA_SERVER_PORT", _serverPort); _serverPort = config->getPropertyAsInteger("EPICS_PVAS_SERVER_PORT", _serverPort); _ifaceAddr.ia.sin_port = htons(_serverPort); _broadcastPort = config->getPropertyAsInteger("EPICS_PVA_BROADCAST_PORT", _broadcastPort); _broadcastPort = config->getPropertyAsInteger("EPICS_PVAS_BROADCAST_PORT", _broadcastPort); _receiveBufferSize = config->getPropertyAsInteger("EPICS_PVA_MAX_ARRAY_BYTES", _receiveBufferSize); _receiveBufferSize = config->getPropertyAsInteger("EPICS_PVAS_MAX_ARRAY_BYTES", _receiveBufferSize); _channelProviderNames = config->getPropertyAsString("EPICS_PVA_PROVIDER_NAMES", _channelProviderNames); _channelProviderNames = config->getPropertyAsString("EPICS_PVAS_PROVIDER_NAMES", _channelProviderNames); // // introspect network interfaces // SOCKET sock = epicsSocketCreate(AF_INET, SOCK_STREAM, 0); if (!sock) { THROW_BASE_EXCEPTION("Failed to create a socket needed to introspect network interfaces."); } if (discoverInterfaces(_ifaceList, sock, &_ifaceAddr)) { THROW_BASE_EXCEPTION("Failed to introspect network interfaces."); } else if (_ifaceList.size() == 0) { THROW_BASE_EXCEPTION("No (specified) network interface(s) available."); } epicsSocketDestroy(sock); }
int Eiger::connect (void) { const char *functionName = "connect"; if(!mSockClosed) return EXIT_SUCCESS; mSockFd = epicsSocketCreate(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(mSockFd == INVALID_SOCKET) { ERR("couldn't create socket"); return EXIT_FAILURE; } setNonBlock(true); if(::connect(mSockFd, (struct sockaddr*)&mAddress, sizeof(mAddress)) < 0) { // Connection actually failed if(errno != EINPROGRESS) { char error[MAX_BUF_SIZE]; epicsSocketConvertErrnoToString(error, sizeof(error)); ERR_ARGS("failed to connect to %s:%d [%s]", mHostname, HTTP_PORT, error); epicsSocketDestroy(mSockFd); return EXIT_FAILURE; } // Server didn't respond immediately, wait a little else { fd_set set; struct timeval tv; int ret; FD_ZERO(&set); FD_SET(mSockFd, &set); tv.tv_sec = DEFAULT_TIMEOUT_CONNECT; tv.tv_usec = 0; ret = select(mSockFd + 1, NULL, &set, NULL, &tv); if(ret <= 0) { const char *error = ret == 0 ? "TIMEOUT" : "select failed"; ERR_ARGS("failed to connect to %s:%d [%s]", mHostname, HTTP_PORT, error); epicsSocketDestroy(mSockFd); return EXIT_FAILURE; } } } setNonBlock(false); mSockClosed = false; return EXIT_SUCCESS; }
Transport::shared_pointer BlockingUDPConnector::connect(TransportClient::shared_pointer const & /*client*/, auto_ptr<ResponseHandler>& responseHandler, osiSockAddr& bindAddress, int8 transportRevision, int16 /*priority*/) { LOG(logLevelDebug, "Creating datagram socket to: %s.", inetAddressToString(bindAddress).c_str()); SOCKET socket = epicsSocketCreate(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(socket==INVALID_SOCKET) { char errStr[64]; epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); LOG(logLevelError, "Error creating socket: %s.", errStr); return Transport::shared_pointer(); } int optval = _broadcast ? 1 : 0; int retval = ::setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval)); if(retval<0) { char errStr[64]; epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); LOG(logLevelError, "Error setting SO_BROADCAST: %s.", errStr); epicsSocketDestroy (socket); return Transport::shared_pointer(); } /* IPv4 multicast addresses are defined by the leading address bits of 1110, originating from the classful network design of the early Internet when this group of addresses was designated as Class D. The Classless Inter-Domain Routing (CIDR) prefix of this group is 224.0.0.0/4. The group includes the addresses from 224.0.0.0 to 239.255.255.255. Address assignments from within this range are specified in RFC 5771, an Internet Engineering Task Force (IETF) Best Current Practice document (BCP 51).*/ // set SO_REUSEADDR or SO_REUSEPORT, OS dependant if (_reuseSocket) epicsSocketEnableAddressUseForDatagramFanout(socket); retval = ::bind(socket, (sockaddr*)&(bindAddress.sa), sizeof(sockaddr)); if(retval<0) { char errStr[64]; epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); LOG(logLevelError, "Error binding socket: %s.", errStr); epicsSocketDestroy (socket); return Transport::shared_pointer(); } // sockets are blocking by default Transport::shared_pointer transport = BlockingUDPTransport::create(_serverFlag, responseHandler, socket, bindAddress, transportRevision); return transport; }
int E5810Reboot(char * inetAddr,char *password) { struct sockaddr_in serverAddr; SOCKET fd; int status; int nbytes; if(password==0 || strlen(password)<2) password = defaultPassword; errno = 0; fd = epicsSocketCreate(PF_INET, SOCK_STREAM, 0); if(fd == -1) { printf("can't create socket %s\n",strerror(errno)); return(-1); } memset((char*)&serverAddr, 0, sizeof(struct sockaddr_in)); serverAddr.sin_family = PF_INET; /* 23 is telnet port */ status = aToIPAddr(inetAddr,23,&serverAddr); if(status) { printf("aToIPAddr failed\n"); return(-1); } errno = 0; status = connect(fd,(struct sockaddr*)&serverAddr, sizeof(serverAddr)); if(status) { printf("can't connect %s\n",strerror (errno)); epicsSocketDestroy(fd); return(-1); } nbytes = send(fd,"reboot\n",7,0); if(nbytes!=7) printf("nbytes %d expected 7\n",nbytes); epicsThreadSleep(1.0); nbytes = send(fd,password,(int)strlen(password),0); if(nbytes!=strlen(password)) printf("nbytes %d expected %d\n",nbytes,(int)strlen(password)); epicsThreadSleep(1.0); nbytes = send(fd,"\ny\n",3,0); if(nbytes!=3) printf("nbytes %d expected 3\n",nbytes); epicsThreadSleep(1.0); epicsSocketDestroy(fd); epicsThreadSleep(20.0); return(0); }
SOCKET shCreateSocket(int domain, int type, int protocol) { SOCKET sd = epicsSocketCreate(domain, type, protocol); int ret; osiSockIoctl_t flag; if(sd==INVALID_SOCKET) return sd; /* set non-blocking IO */ flag = 1; ret = socket_ioctl(sd, FIONBIO, &flag); if(ret) { epicsSocketDestroy(sd); sd = INVALID_SOCKET; } return sd; }
int TDS3000Reboot(char * inetAddr) { struct sockaddr_in serverAddr; int fd; int status; int nbytes; char *url; int urlLen; url = "GET /resetinst.cgi HTTP/1.0\n\n"; urlLen = strlen(url); errno = 0; fd = epicsSocketCreate(PF_INET, SOCK_STREAM, 0); if(fd == -1) { printf("can't create socket %s\n",strerror(errno)); return(-1); } memset((char*)&serverAddr, 0, sizeof(struct sockaddr_in)); serverAddr.sin_family = PF_INET; /* 80 is http port */ status = aToIPAddr(inetAddr,80,&serverAddr); if(status) { printf("aToIPAddr failed\n"); return(-1); } errno = 0; status = connect(fd,(struct sockaddr*)&serverAddr, sizeof(serverAddr)); if(status) { printf("can't connect %s\n",strerror (errno)); close(fd); return(-1); } nbytes = send(fd,url,urlLen,0); if(nbytes!=urlLen) printf("nbytes %d expected %d\n",nbytes,urlLen); close(fd); return(0); }
SOCKET BlockingTCPConnector::tryConnect(osiSockAddr& address, int tries) { char strBuffer[64]; ipAddrToDottedIP(&address.ia, strBuffer, sizeof(strBuffer)); for(int tryCount = 0; tryCount<tries; tryCount++) { LOG(logLevelDebug, "Opening socket to PVA server %s, attempt %d.", strBuffer, tryCount+1); SOCKET socket = epicsSocketCreate(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (socket == INVALID_SOCKET) { epicsSocketConvertErrnoToString(strBuffer, sizeof(strBuffer)); std::ostringstream temp; temp<<"Socket create error: "<<strBuffer; THROW_EXCEPTION2(std::runtime_error, temp.str()); } else { // TODO: use non-blocking connect() to have controllable timeout if(::connect(socket, &address.sa, sizeof(sockaddr))==0) { return socket; } else { epicsSocketConvertErrnoToString(strBuffer, sizeof(strBuffer)); char saddr[32]; sockAddrToDottedIP(&address.sa, saddr, sizeof(saddr)); epicsSocketDestroy (socket); std::ostringstream temp; temp<<"error connecting to "<<saddr<<" : "<<strBuffer; throw std::runtime_error(temp.str()); } } } return INVALID_SOCKET; }
/* * caStartRepeaterIfNotInstalled () * * Test for the repeater already installed * * NOTE: potential race condition here can result * in two copies of the repeater being spawned * however the repeater detects this, prints a message, * and lets the other task start the repeater. * * QUESTION: is there a better way to test for a port in use? * ANSWER: none that I can find. * * Problems with checking for the repeater installed * by attempting to bind a socket to its address * and port. * * 1) Closed socket may not release the bound port * before the repeater wakes up and tries to grab it. * Attempting to bind the open socket to another port * also does not work. * * 072392 - problem solved by using SO_REUSEADDR */ void epicsShareAPI caStartRepeaterIfNotInstalled ( unsigned repeaterPort ) { bool installed = false; int status; SOCKET tmpSock; union { struct sockaddr_in ia; struct sockaddr sa; } bd; if ( repeaterPort > 0xffff ) { fprintf ( stderr, "caStartRepeaterIfNotInstalled () : strange repeater port specified\n" ); return; } tmpSock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); if ( tmpSock != INVALID_SOCKET ) { ca_uint16_t port = static_cast < ca_uint16_t > ( repeaterPort ); memset ( (char *) &bd, 0, sizeof ( bd ) ); bd.ia.sin_family = AF_INET; bd.ia.sin_addr.s_addr = htonl ( INADDR_ANY ); bd.ia.sin_port = htons ( port ); status = bind ( tmpSock, &bd.sa, sizeof ( bd ) ); if ( status < 0 ) { if ( SOCKERRNO == SOCK_EADDRINUSE ) { installed = true; } else { fprintf ( stderr, "caStartRepeaterIfNotInstalled () : bind failed\n" ); } } } /* * turn on reuse only after the test so that * this works on kernels that support multicast */ epicsSocketEnableAddressReuseDuringTimeWaitState ( tmpSock ); epicsSocketDestroy ( tmpSock ); if ( ! installed ) { /* * This is not called if the repeater is known to be * already running. (in the event of a race condition * the 2nd repeater exits when unable to attach to the * repeater's port) */ /* * look for a caRepeater in the same directory as CA.DLL * and use this if present instead of a PATH search */ char carep_path[256]; strcpy(carep_path, "caRepeater"); #ifdef _WIN32 char caDLLPath[MAX_PATH]; HMODULE hmod = GetModuleHandle("CA.DLL"); if (hmod != NULL) { if (GetModuleFileName(hmod, caDLLPath, sizeof(caDLLPath)) > 0) { char* base_path = strrchr(caDLLPath, '\\'); if (base_path != NULL) { *base_path = '\0'; // caDLLPath is now the directory containing CA.DLL _snprintf(carep_path, sizeof(carep_path), "%s\\caRepeater.exe", caDLLPath); if (access(carep_path, 04) != 0) { strcpy(carep_path, "caRepeater"); // Not found, so will search PATH instead for caRepeater } } } } #endif /* _WIN32 */ osiSpawnDetachedProcessReturn osptr = osiSpawnDetachedProcess ( "CA Repeater", carep_path ); if ( osptr == osiSpawnDetachedProcessNoSupport ) { epicsThreadId tid; tid = epicsThreadCreate ( "CAC-repeater", epicsThreadPriorityLow, epicsThreadGetStackSize ( epicsThreadStackMedium ), caRepeaterThread, 0); if ( tid == 0 ) { fprintf ( stderr, "caStartRepeaterIfNotInstalled : unable to create CA repeater daemon thread\n" ); } } else if ( osptr == osiSpawnDetachedProcessFail ) { fprintf ( stderr, "caStartRepeaterIfNotInstalled (): unable to start CA repeater daemon detached process\n" ); } } }
/* * * req_server() * * CA server task * * Waits for connections at the CA port and spawns a task to * handle each of them * */ static void req_server (void *pParm) { unsigned priorityOfSelf = epicsThreadGetPrioritySelf (); unsigned priorityOfBeacons; epicsThreadBooleanStatus tbs; struct sockaddr_in serverAddr; /* server's address */ osiSocklen_t addrSize; int status; SOCKET clientSock; epicsThreadId tid; int portChange; epicsSignalInstallSigPipeIgnore (); taskwdInsert ( epicsThreadGetIdSelf (), NULL, NULL ); rsrvCurrentClient = epicsThreadPrivateCreate (); if ( envGetConfigParamPtr ( &EPICS_CAS_SERVER_PORT ) ) { ca_server_port = envGetInetPortConfigParam ( &EPICS_CAS_SERVER_PORT, (unsigned short) CA_SERVER_PORT ); } else { ca_server_port = envGetInetPortConfigParam ( &EPICS_CA_SERVER_PORT, (unsigned short) CA_SERVER_PORT ); } if (IOC_sock != 0 && IOC_sock != INVALID_SOCKET) { epicsSocketDestroy ( IOC_sock ); } /* * Open the socket. Use ARPA Internet address format and stream * sockets. Format described in <sys/socket.h>. */ if ( ( IOC_sock = epicsSocketCreate (AF_INET, SOCK_STREAM, 0) ) == INVALID_SOCKET ) { errlogPrintf ("CAS: Socket creation error\n"); epicsThreadSuspendSelf (); } epicsSocketEnableAddressReuseDuringTimeWaitState ( IOC_sock ); /* Zero the sock_addr structure */ memset ( (void *) &serverAddr, 0, sizeof ( serverAddr ) ); serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = htonl (INADDR_ANY); serverAddr.sin_port = htons ( ca_server_port ); /* get server's Internet address */ status = bind ( IOC_sock, (struct sockaddr *) &serverAddr, sizeof ( serverAddr ) ); if ( status < 0 ) { if ( SOCKERRNO == SOCK_EADDRINUSE ) { /* * enable assignment of a default port * (so the getsockname() call below will * work correctly) */ serverAddr.sin_port = ntohs (0); status = bind ( IOC_sock, (struct sockaddr *) &serverAddr, sizeof ( serverAddr ) ); } if ( status < 0 ) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); errlogPrintf ( "CAS: Socket bind error was \"%s\"\n", sockErrBuf ); epicsThreadSuspendSelf (); } portChange = 1; } else { portChange = 0; } addrSize = ( osiSocklen_t ) sizeof ( serverAddr ); status = getsockname ( IOC_sock, (struct sockaddr *)&serverAddr, &addrSize); if ( status ) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); errlogPrintf ( "CAS: getsockname() error %s\n", sockErrBuf ); epicsThreadSuspendSelf (); } ca_server_port = ntohs (serverAddr.sin_port); if ( portChange ) { errlogPrintf ( "cas warning: Configured TCP port was unavailable.\n"); errlogPrintf ( "cas warning: Using dynamically assigned TCP port %hu,\n", ca_server_port ); errlogPrintf ( "cas warning: but now two or more servers share the same UDP port.\n"); errlogPrintf ( "cas warning: Depending on your IP kernel this server may not be\n" ); errlogPrintf ( "cas warning: reachable with UDP unicast (a host's IP in EPICS_CA_ADDR_LIST)\n" ); } /* listen and accept new connections */ if ( listen ( IOC_sock, 20 ) < 0 ) { errlogPrintf ("CAS: Listen error\n"); epicsSocketDestroy (IOC_sock); epicsThreadSuspendSelf (); } tbs = epicsThreadHighestPriorityLevelBelow ( priorityOfSelf, &priorityOfBeacons ); if ( tbs != epicsThreadBooleanStatusSuccess ) { priorityOfBeacons = priorityOfSelf; } beacon_startStopEvent = epicsEventMustCreate(epicsEventEmpty); beacon_ctl = ctlPause; tid = epicsThreadCreate ( "CAS-beacon", priorityOfBeacons, epicsThreadGetStackSize (epicsThreadStackSmall), rsrv_online_notify_task, 0 ); if ( tid == 0 ) { epicsPrintf ( "CAS: unable to start beacon thread\n" ); } epicsEventMustWait(beacon_startStopEvent); epicsEventSignal(castcp_startStopEvent); while (TRUE) { struct sockaddr sockAddr; osiSocklen_t addLen = sizeof(sockAddr); while (castcp_ctl == ctlPause) { epicsThreadSleep(0.1); } clientSock = epicsSocketAccept ( IOC_sock, &sockAddr, &addLen ); if ( clientSock == INVALID_SOCKET ) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); errlogPrintf("CAS: Client accept error was \"%s\"\n", sockErrBuf ); epicsThreadSleep(15.0); continue; } else { epicsThreadId id; struct client *pClient; /* socket passed in is closed if unsuccessful here */ pClient = create_tcp_client ( clientSock ); if ( ! pClient ) { epicsThreadSleep ( 15.0 ); continue; } LOCK_CLIENTQ; ellAdd ( &clientQ, &pClient->node ); UNLOCK_CLIENTQ; id = epicsThreadCreate ( "CAS-client", epicsThreadPriorityCAServerLow, epicsThreadGetStackSize ( epicsThreadStackBig ), camsgtask, pClient ); if ( id == 0 ) { LOCK_CLIENTQ; ellDelete ( &clientQ, &pClient->node ); UNLOCK_CLIENTQ; destroy_tcp_client ( pClient ); errlogPrintf ( "CAS: task creation for new client failed\n" ); epicsThreadSleep ( 15.0 ); continue; } } } }
static long init_record(void *precord, int pass) { aliveRecord *prec; struct rpvtStruct *prpvt; epicsTimeStamp start_time; int i, flag; char *p; prec = precord; if( pass == 0) { // last element of struct rpvtStruct keeps coming out as // zero length array, so pad it a bit to do a kludge fix prec->rpvt = calloc(1, sizeof(struct rpvtStruct) + 16); return 0; } prec->val = 0; sprintf( prec->ver, "%d-%d-%d", ALIVE_VERSION, ALIVE_REVISION, ALIVE_MODIFICATION ); prpvt = prec->rpvt; // save value to local structure, set to zero until initialized. prpvt->orig_port = prec->iport; prec->iport = 0; // if period is set to 0, use default of 15 if( !prec->hprd) prec->hprd = 15; prpvt->fault_flag = 0; prpvt->ready_flag = 0; prpvt->flags = 0; // first bit set when port initialized epicsTimeGetCurrent(&start_time); prpvt->incarnation = (uint32_t) start_time.secPastEpoch; for( i = 0; i < ENV_CNT; i++) { flag = sscanf( *(&prec->env1 + i), "%s", prpvt->env[i]); if( !flag) prpvt->env[i][0] = '\0'; } if( (prpvt->socket = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) { errlogSevPrintf( errlogFatal, "%s", "alive record: " "Won't start, can't open DGRAM socket.\n"); prpvt->fault_flag = 1; return 1; } #ifdef vxWorks bzero( (void *) &(prpvt->h_addr), sizeof(struct sockaddr_in) ); #else memset( (void *) &(prpvt->h_addr), 0, sizeof(struct sockaddr_in) ); #endif prpvt->h_addr.sin_family = AF_INET; prpvt->h_addr.sin_port = htons(prec->rport); #if defined (vxWorks) prpvt->h_addr.sin_len = (u_char) sizeof (struct sockaddr_in); if( (prpvt->h_addr.sin_addr.s_addr = inet_addr (prec->rhost)) != ERROR) #elif defined (_WIN32) if ((prpvt->h_addr.sin_addr.s_addr = inet_addr(prec->rhost)) != INADDR_NONE) #else if( inet_aton( prec->rhost, &(prpvt->h_addr.sin_addr)) ) #endif prpvt->ready_flag = 1; p = prec->iocnm; while(*p != '\0') { if( (*p != ' ') && (*p != '\t')) break; p++; } if( *p != '\0') { strncpy(prpvt->ioc_name, p, 39); prpvt->ioc_name[39] = '\0'; strcpy( prec->nmvar, "----"); } else { p = getenv(prec->nmvar); if( p == NULL) { errlogSevPrintf( errlogFatal, "%s", "alive record: " "Won't start, can't get IOC name environment variable.\n"); prpvt->fault_flag = 1; return 1; } // condition is sanity check, as the output buffer is static if( strlen( p) > 39) { errlogSevPrintf( errlogFatal, "%s", "alive record: " "Won't start, environment variable IOC too long.\n"); prpvt->fault_flag = 1; return 1; } strncpy(prpvt->ioc_name, p, 39); prpvt->ioc_name[39] = '\0'; strncpy(prec->iocnm, prpvt->ioc_name, 40); } prpvt->listen_thread = epicsThreadCreate("alive_tcp_listen_thread", 51, epicsThreadGetStackSize(epicsThreadStackMedium), (EPICSTHREADFUNC) ioc_alive_listen, (void *) precord); prpvt->send_thread = epicsThreadCreate("alive_udp_send_thread", 50, epicsThreadGetStackSize(epicsThreadStackMedium), (EPICSTHREADFUNC) ioc_alive_send, (void *) precord); return 0; }
void *ioc_alive_listen(void *data) { aliveRecord *prec = (aliveRecord *) data; struct rpvtStruct *prpvt; SOCKET tcp_sockfd; int sflag; SOCKET client_sockfd; struct sockaddr_in l_addr; osiSocklen_t socklen; char *q; // key and value lengths, key length of zero means it doesn't exist int env_len[ENV_CNT][2]; uint32_t msg32; uint16_t msg16, len16; uint8_t len8; int length; int number; int type; #if defined (vxWorks) BOOT_PARAMS bootparams; #endif #if defined (linux) || defined (darwin) char *user; char *group; char *hostname; char hostname_buffer[129]; #endif #if defined (_WIN32) char *user; char user_buffer[80]; char *machine; char machine_buffer[20]; #endif int i; prpvt = prec->rpvt; #if defined (vxWorks) type = 1; #elif defined (linux) type = 2; #elif defined (darwin) type = 3; #elif defined (_WIN32) type = 4; #else type = 0; #endif #ifdef vxWorks bzero( (char *) &l_addr, sizeof( struct sockaddr_in) ); l_addr.sin_len = sizeof( struct sockaddr_in); #else memset( &l_addr, 0, sizeof( struct sockaddr_in) ); #endif l_addr.sin_family = AF_INET; l_addr.sin_addr.s_addr = htonl(INADDR_ANY); l_addr.sin_port = htons(prpvt->orig_port); if( (tcp_sockfd = epicsSocketCreate(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET ) { perror("socket"); prec->ipsts = aliveIPSTS_INOPERABLE; monitor_field(prec, (void *) &prec->ipsts); return NULL; } sflag = 1; // not the end of the world if this option doesn't work setsockopt(tcp_sockfd, SOL_SOCKET, SO_REUSEADDR, (void *) &sflag, sizeof(sflag)); if( bind(tcp_sockfd, (struct sockaddr *) &l_addr, sizeof(struct sockaddr_in)) ) { perror("TCP bind"); prec->ipsts = aliveIPSTS_INOPERABLE; monitor_field(prec, (void *) &prec->ipsts); return NULL; } socklen = sizeof(struct sockaddr_in); if( getsockname( tcp_sockfd, (struct sockaddr *) &l_addr, &socklen) ) { perror("TCP getsockname"); prec->ipsts = aliveIPSTS_INOPERABLE; monitor_field(prec, (void *) &prec->ipsts); return NULL; } // wait to use result until we know listen() works if( listen(tcp_sockfd, 5) ) { perror("TCP listen"); prec->ipsts = aliveIPSTS_INOPERABLE; monitor_field(prec, (void *) &prec->ipsts); return NULL; } prec->iport = ntohs(l_addr.sin_port); monitor_field(prec, (void *) &prec->iport); prec->ipsts = aliveIPSTS_OPERABLE; monitor_field(prec, (void *) &prec->ipsts); // request remote read prpvt->flags |= ((uint16_t) 1); while(1) { struct sockaddr r_addr; osiSocklen_t r_len = sizeof( r_addr); client_sockfd = epicsSocketAccept( tcp_sockfd, &r_addr, &r_len); if (client_sockfd == INVALID_SOCKET) continue; // fault flag can't happen, but just in case if( prec->isup || prpvt->fault_flag || !prpvt->ready_flag || ( ((struct sockaddr_in *)&r_addr)->sin_addr.s_addr != prpvt->h_addr.sin_addr.s_addr) ) { epicsSocketDestroy(client_sockfd); continue; } // TCP protocol version msg16 = htons(PROTOCOL_VERSION); send( client_sockfd, (void *) &msg16, sizeof(uint16_t), 0); // IOC type, currently 1 = vxworks, 2 = linux, 3 = darwin msg16 = htons(type); send( client_sockfd, (void *) &msg16, sizeof(uint16_t), 0); number = 0; length = 10; // from version + type + number + length #if defined (vxWorks) memset( &bootparams, 0, sizeof( BOOT_PARAMS) ); bootStringToStruct( sysBootLine, &bootparams); // don't check to see if it returns EOS, as it's zeroed out length += 12; // bootparams.unitNum, bootparams.procNum, bootparams.flags length += 12; // 8-bit lengths below length += ((uint8_t) strlen(bootparams.bootDev) ); length += ((uint8_t) strlen(bootparams.hostName) ); length += ((uint8_t) strlen(bootparams.bootFile) ); length += ((uint8_t) strlen(bootparams.ead) ); length += ((uint8_t) strlen(bootparams.bad) ); length += ((uint8_t) strlen(bootparams.had) ); length += ((uint8_t) strlen(bootparams.gad) ); length += ((uint8_t) strlen(bootparams.usr) ); length += ((uint8_t) strlen(bootparams.passwd) ); length += ((uint8_t) strlen(bootparams.targetName) ); length += ((uint8_t) strlen(bootparams.startupScript) ); length += ((uint8_t) strlen(bootparams.other) ); #endif #if defined (linux) || defined (darwin) { uid_t user_id; gid_t group_id; struct passwd *passwd_entry; struct group *group_entry; user_id = getuid(); passwd_entry = getpwuid(user_id); if( passwd_entry != NULL) user = passwd_entry->pw_name; else user = NULL; group_id = getgid(); group_entry = getgrgid(group_id); if( group_entry != NULL) group = group_entry->gr_name; else group = NULL; if( gethostname( hostname_buffer, 128) ) hostname = NULL; else { hostname_buffer[128] = '\0'; hostname = hostname_buffer; } } // flag == 2 or 3 length += 1; // 8-bit string length if( user != NULL) length += ((uint8_t) strlen(user) ); length += 1; // 8-bit string length if( group != NULL) length += ((uint8_t) strlen(group) ); length += 1; // 8-bit string length if( hostname != NULL) length += ((uint8_t) strlen(hostname) ); #endif #if defined (_WIN32) { uint32_t size; length += 2; // two variable lengths size = 80; if (GetUserNameA(user_buffer, &size)) { user = user_buffer; length += ((uint8_t)strlen(user)); } else user = NULL; size = 20; if (GetComputerNameA(machine_buffer, &size)) { machine = machine_buffer; length += ((uint8_t)strlen(machine)); } else machine = NULL; } #endif for( i = 0; i < ENV_CNT; i++) { if( prpvt->env[i][0] == '\0') env_len[i][0] = 0; else { number++; length += 3; // 8-bit key & 16-bit value string lengths env_len[i][0] = strlen(prpvt->env[i]); length += env_len[i][0]; q = getenv(prpvt->env[i]); if( q == NULL) env_len[i][1] = 0; else { env_len[i][1] = strlen(q); // if size is greater that 16-bit max, truncate to zero if( env_len[i][1] > 65535) env_len[i][1] = 0; length += env_len[i][1]; } } } /* printf("%d\n", length); fflush(stdout); */ msg32 = htonl( length); send( client_sockfd, (void *) &msg32, sizeof(uint32_t), 0); msg16 = htons( number); send( client_sockfd, (void *) &msg16, sizeof(uint16_t), 0); for( i = 0; i < ENV_CNT; i++) { if( env_len[i][0] == 0) continue; len8 = env_len[i][0]; send( client_sockfd, (void *) &len8, sizeof(uint8_t), 0); send( client_sockfd, prpvt->env[i], len8, 0); q = getenv(prpvt->env[i]); len16 = env_len[i][1]; msg16 = htons( len16); send( client_sockfd, (void *) &msg16, sizeof(uint16_t), 0); if( len16) send( client_sockfd, q, len16, 0); } #ifdef vxWorks bootparam_send( client_sockfd, bootparams.bootDev); msg32 = htonl(bootparams.unitNum); send( client_sockfd, (void *) &msg32, sizeof(uint32_t), 0); msg32 = htonl(bootparams.procNum); send( client_sockfd, (void *) &msg32, sizeof(uint32_t), 0); bootparam_send( client_sockfd, bootparams.hostName); bootparam_send( client_sockfd, bootparams.bootFile); bootparam_send( client_sockfd, bootparams.ead); bootparam_send( client_sockfd, bootparams.bad); bootparam_send( client_sockfd, bootparams.had); bootparam_send( client_sockfd, bootparams.gad); bootparam_send( client_sockfd, bootparams.usr); bootparam_send( client_sockfd, bootparams.passwd); msg32 = htonl( bootparams.flags); send( client_sockfd, (void *) &msg32, sizeof(uint32_t), 0); bootparam_send( client_sockfd, bootparams.targetName); bootparam_send( client_sockfd, bootparams.startupScript); bootparam_send( client_sockfd, bootparams.other); #endif #if defined (linux) || defined (darwin) if( user == NULL) len8 = 0; else len8 = strlen( user); send( client_sockfd, (void *) &len8, sizeof(uint8_t), 0); if( user != NULL) send( client_sockfd, user, len8, 0); if( group == NULL) len8 = 0; else len8 = strlen( group); send( client_sockfd, (void *) &len8, sizeof(uint8_t), 0); if( group != NULL) send( client_sockfd, group, len8, 0); if( hostname == NULL) len8 = 0; else len8 = strlen( hostname); send( client_sockfd, (void *) &len8, sizeof(uint8_t), 0); if( hostname != NULL) send( client_sockfd, hostname, len8, 0); #endif #if defined (_WIN32) if (user == NULL) len8 = 0; else len8 = strlen(user); send(client_sockfd, (void *)&len8, sizeof(uint8_t), 0); if (user != NULL) send(client_sockfd, user, len8, 0); if (machine == NULL) len8 = 0; else len8 = strlen(machine); send(client_sockfd, (void *)&len8, sizeof(uint8_t), 0); if (machine != NULL) send(client_sockfd, machine, len8, 0); #endif epicsSocketDestroy( client_sockfd); // turn off request flag prpvt->flags &= ~((uint16_t) 1); // if itrigger was set, unset it if( prec->itrig) { prec->itrig = 0; monitor_field(prec, (void *) &prec->itrig); } } return NULL; }
/* * CAST_SERVER * * service UDP messages * */ void cast_server(void *pParm) { struct sockaddr_in sin; int status; int count=0; struct sockaddr_in new_recv_addr; osiSocklen_t recv_addr_size; unsigned short port; osiSockIoctl_t nchars; if ( envGetConfigParamPtr ( &EPICS_CAS_SERVER_PORT ) ) { port = envGetInetPortConfigParam ( &EPICS_CAS_SERVER_PORT, (unsigned short) CA_SERVER_PORT ); } else { port = envGetInetPortConfigParam ( &EPICS_CA_SERVER_PORT, (unsigned short) CA_SERVER_PORT ); } recv_addr_size = sizeof(new_recv_addr); if( IOC_cast_sock!=0 && IOC_cast_sock!=INVALID_SOCKET ) { epicsSocketDestroy ( IOC_cast_sock ); } /* * Open the socket. * Use ARPA Internet address format and datagram socket. */ if ( ( IOC_cast_sock = epicsSocketCreate (AF_INET, SOCK_DGRAM, 0) ) == INVALID_SOCKET ) { epicsPrintf ("CAS: cast socket creation error\n"); epicsThreadSuspendSelf (); } /* * some concern that vxWorks will run out of mBuf's * if this change is made * * joh 11-10-98 */ #if 0 { /* * * this allows for faster connects by queuing * additional incomming UDP search frames * * this allocates a 32k buffer * (uses a power of two) */ int size = 1u<<15u; status = setsockopt (IOC_cast_sock, SOL_SOCKET, SO_RCVBUF, (char *)&size, sizeof(size)); if (status<0) { epicsPrintf ("CAS: unable to set cast socket size\n"); } } #endif epicsSocketEnableAddressUseForDatagramFanout ( IOC_cast_sock ); /* Zero the sock_addr structure */ memset((char *)&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(port); /* get server's Internet address */ if( bind(IOC_cast_sock, (struct sockaddr *)&sin, sizeof (sin)) < 0){ char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); epicsPrintf ("CAS: UDP server port bind error was \"%s\"\n", sockErrBuf ); epicsSocketDestroy ( IOC_cast_sock ); epicsThreadSuspendSelf (); } /* * setup new client structure but reuse old structure if * possible * */ while ( TRUE ) { prsrv_cast_client = create_client ( IOC_cast_sock, IPPROTO_UDP ); if ( prsrv_cast_client ) { break; } epicsThreadSleep(300.0); } casAttachThreadToClient ( prsrv_cast_client ); /* * add placeholder for the first version message should it be needed */ rsrv_version_reply ( prsrv_cast_client ); epicsEventSignal(casudp_startStopEvent); while (TRUE) { status = recvfrom ( IOC_cast_sock, prsrv_cast_client->recv.buf, prsrv_cast_client->recv.maxstk, 0, (struct sockaddr *)&new_recv_addr, &recv_addr_size); if (status < 0) { if (SOCKERRNO != SOCK_EINTR) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); epicsPrintf ("CAS: UDP recv error (errno=%s)\n", sockErrBuf); epicsThreadSleep(1.0); } } else if (casudp_ctl == ctlRun) { prsrv_cast_client->recv.cnt = (unsigned) status; prsrv_cast_client->recv.stk = 0ul; epicsTimeGetCurrent(&prsrv_cast_client->time_at_last_recv); prsrv_cast_client->minor_version_number = 0; prsrv_cast_client->seqNoOfReq = 0; /* * If we are talking to a new client flush to the old one * in case we are holding UDP messages waiting to * see if the next message is for this same client. */ if (prsrv_cast_client->send.stk>sizeof(caHdr)) { status = memcmp( (void *)&prsrv_cast_client->addr, (void *)&new_recv_addr, recv_addr_size); if(status){ /* * if the address is different */ cas_send_dg_msg(prsrv_cast_client); prsrv_cast_client->addr = new_recv_addr; } } else { prsrv_cast_client->addr = new_recv_addr; } if (CASDEBUG>1) { char buf[40]; ipAddrToDottedIP (&prsrv_cast_client->addr, buf, sizeof(buf)); errlogPrintf ("CAS: cast server msg of %d bytes from addr %s\n", prsrv_cast_client->recv.cnt, buf); } if (CASDEBUG>2) count = ellCount (&prsrv_cast_client->chanList); status = camessage ( prsrv_cast_client ); if(status == RSRV_OK){ if(prsrv_cast_client->recv.cnt != prsrv_cast_client->recv.stk){ char buf[40]; ipAddrToDottedIP (&prsrv_cast_client->addr, buf, sizeof(buf)); epicsPrintf ("CAS: partial (damaged?) UDP msg of %d bytes from %s ?\n", prsrv_cast_client->recv.cnt-prsrv_cast_client->recv.stk, buf); } } else { char buf[40]; ipAddrToDottedIP (&prsrv_cast_client->addr, buf, sizeof(buf)); epicsPrintf ("CAS: invalid (damaged?) UDP request from %s ?\n", buf); } if (CASDEBUG>2) { if ( ellCount (&prsrv_cast_client->chanList) ) { errlogPrintf ("CAS: Fnd %d name matches (%d tot)\n", ellCount(&prsrv_cast_client->chanList)-count, ellCount(&prsrv_cast_client->chanList)); } } } /* * allow messages to batch up if more are comming */ nchars = 0; /* supress purify warning */ status = socket_ioctl(IOC_cast_sock, FIONREAD, &nchars); if (status<0) { errlogPrintf ("CA cast server: Unable to fetch N characters pending\n"); cas_send_dg_msg (prsrv_cast_client); clean_addrq (); } else if (nchars == 0) { cas_send_dg_msg (prsrv_cast_client); clean_addrq (); } } }
/* * Create a link */ static asynStatus connectIt(void *drvPvt, asynUser *pasynUser) { ttyController_t *tty = (ttyController_t *)drvPvt; SOCKET fd; int i; /* * Sanity check */ assert(tty); asynPrint(pasynUser, ASYN_TRACE_FLOW, "Open connection to %s reason:%d fd:%d\n", tty->IPDeviceName, pasynUser->reason, tty->fd); if (tty->fd != INVALID_SOCKET) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s: Link already open!", tty->IPDeviceName); return asynError; } else if(tty->flags & FLAG_SHUTDOWN) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s: Link shutdown!", tty->IPDeviceName); return asynError; } /* If pasynUser->reason > 0) then use this as the file descriptor */ if (pasynUser->reason > 0) { fd = pasynUser->reason; } else { /* * Create the socket */ if ((fd = epicsSocketCreate(tty->farAddr.oa.sa.sa_family, tty->socketType, 0)) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't create socket: %s", strerror(SOCKERRNO)); return asynError; } /* * Enable broadcasts if so requested */ i = 1; if ((tty->flags & FLAG_BROADCAST) && (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (void *)&i, sizeof i) < 0)) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't set %s socket BROADCAST option: %s", tty->IPDeviceName, strerror(SOCKERRNO)); epicsSocketDestroy(fd); return asynError; } /* * Convert host name/number to IP address. * We delay doing this until now in case a device * has just appeared in a DNS database. */ if (tty->flags & FLAG_NEED_LOOKUP) { if(hostToIPAddr(tty->IPHostName, &tty->farAddr.oa.ia.sin_addr) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Unknown host \"%s\"", tty->IPHostName); epicsSocketDestroy(fd); return asynError; } tty->flags &= ~FLAG_NEED_LOOKUP; tty->flags |= FLAG_DONE_LOOKUP; } /* * Bind to the local IP address if it was specified. * This is a very unusual configuration */ if (tty->localAddrSize > 0) { if (bind(fd, &tty->localAddr.sa, tty->localAddrSize)) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "unable to bind to local port: %s", strerror(SOCKERRNO)); epicsSocketDestroy(fd); return asynError; } } /* * Connect to the remote host * If the connect fails, arrange for another DNS lookup in case the * problem is just that the device has DHCP'd itself an new number. */ if (tty->socketType != SOCK_DGRAM) { if (connect(fd, &tty->farAddr.oa.sa, (int)tty->farAddrSize) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't connect to %s: %s", tty->IPDeviceName, strerror(SOCKERRNO)); epicsSocketDestroy(fd); if (tty->flags & FLAG_DONE_LOOKUP) tty->flags |= FLAG_NEED_LOOKUP; return asynError; } } } i = 1; if ((tty->socketType == SOCK_STREAM) && (tty->farAddr.oa.sa.sa_family == AF_INET) && (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *)&i, sizeof i) < 0)) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't set %s socket NODELAY option: %s", tty->IPDeviceName, strerror(SOCKERRNO)); epicsSocketDestroy(fd); return asynError; } #ifdef USE_POLL if (setNonBlock(fd, 1) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't set %s O_NONBLOCK option: %s", tty->IPDeviceName, strerror(SOCKERRNO)); epicsSocketDestroy(fd); return asynError; } #endif asynPrint(pasynUser, ASYN_TRACE_FLOW, "Opened connection to %s\n", tty->IPDeviceName); tty->fd = fd; return asynSuccess; }
int BlockingTCPAcceptor::initialize() { char ipAddrStr[48]; ipAddrToDottedIP(&_bindAddress.ia, ipAddrStr, sizeof(ipAddrStr)); int tryCount = 0; while(tryCount<2) { char strBuffer[64]; LOG(logLevelDebug, "Creating acceptor to %s.", ipAddrStr); _serverSocketChannel = epicsSocketCreate(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(_serverSocketChannel==INVALID_SOCKET) { epicsSocketConvertErrnoToString(strBuffer, sizeof(strBuffer)); ostringstream temp; temp<<"Socket create error: "<<strBuffer; LOG(logLevelError, "%s", temp.str().c_str()); THROW_BASE_EXCEPTION(temp.str().c_str()); } else { //epicsSocketEnableAddressReuseDuringTimeWaitState(_serverSocketChannel); // try to bind int retval = ::bind(_serverSocketChannel, &_bindAddress.sa, sizeof(sockaddr)); if(retval<0) { epicsSocketConvertErrnoToString(strBuffer, sizeof(strBuffer)); LOG(logLevelDebug, "Socket bind error: %s.", strBuffer); if(_bindAddress.ia.sin_port!=0) { // failed to bind to specified bind address, // try to get port dynamically, but only once LOG( logLevelDebug, "Configured TCP port %d is unavailable, trying to assign it dynamically.", ntohs(_bindAddress.ia.sin_port)); _bindAddress.ia.sin_port = htons(0); } else { epicsSocketDestroy(_serverSocketChannel); break; // exit while loop } } else { // if(retval<0) // bind succeeded // update bind address, if dynamically port selection was used if(ntohs(_bindAddress.ia.sin_port)==0) { osiSocklen_t sockLen = sizeof(sockaddr); // read the actual socket info retval = ::getsockname(_serverSocketChannel, &_bindAddress.sa, &sockLen); if(retval<0) { // error obtaining port number epicsSocketConvertErrnoToString(strBuffer, sizeof(strBuffer)); LOG(logLevelDebug, "getsockname error: %s", strBuffer); } else { LOG( logLevelInfo, "Using dynamically assigned TCP port %d.", ntohs(_bindAddress.ia.sin_port)); } } retval = ::listen(_serverSocketChannel, 4); if(retval<0) { epicsSocketConvertErrnoToString(strBuffer, sizeof(strBuffer)); ostringstream temp; temp<<"Socket listen error: "<<strBuffer; LOG(logLevelError, "%s", temp.str().c_str()); THROW_BASE_EXCEPTION(temp.str().c_str()); } _thread.start(); // all OK, return return ntohs(_bindAddress.ia.sin_port); } // successful bind } // successfully obtained socket tryCount++; } // while ostringstream temp; temp<<"Failed to create acceptor to "<<ipAddrStr; THROW_BASE_EXCEPTION(temp.str().c_str()); }
/* * Tests the log prefix code * The prefix is only applied to log messages as they go out to the socket, * so we need to create a server listening on a port, accept connections etc. * This code is a reduced version of the code in iocLogServer. */ static void testLogPrefix(void) { struct sockaddr_in serverAddr; int status; struct timeval timeout; struct sockaddr_in actualServerAddr; osiSocklen_t actualServerAddrSize; char portstring[16]; testDiag("Testing iocLogPrefix"); timeout.tv_sec = 5; /* in seconds */ timeout.tv_usec = 0; memset((void*)prefixmsgbuffer, 0, sizeof prefixmsgbuffer); /* Clear "errlog: <n> messages were discarded" status */ errlogPrintfNoConsole("."); errlogFlush(); sock = epicsSocketCreate(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { testAbort("epicsSocketCreate failed."); } /* We listen on a an available port. */ memset((void *)&serverAddr, 0, sizeof serverAddr); serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(0); status = bind (sock, (struct sockaddr *)&serverAddr, sizeof (serverAddr) ); if (status < 0) { testAbort("bind failed; all ports in use?"); } status = listen(sock, 10); if (status < 0) { testAbort("listen failed!"); } /* Determine the port that the OS chose */ actualServerAddrSize = sizeof actualServerAddr; memset((void *)&actualServerAddr, 0, sizeof serverAddr); status = getsockname(sock, (struct sockaddr *) &actualServerAddr, &actualServerAddrSize); if (status < 0) { testAbort("Can't find port number!"); } sprintf(portstring, "%d", ntohs(actualServerAddr.sin_port)); testDiag("Listening on port %s", portstring); /* Set the EPICS environment variables for logging. */ epicsEnvSet ( "EPICS_IOC_LOG_INET", "localhost" ); epicsEnvSet ( "EPICS_IOC_LOG_PORT", portstring ); pfdctx = (void *) fdmgr_init(); if (status < 0) { testAbort("fdmgr_init failed!"); } status = fdmgr_add_callback(pfdctx, sock, fdi_read, acceptNewClient, &serverAddr); if (status < 0) { testAbort("fdmgr_add_callback failed!"); } testOk1(iocLogInit() == 0); fdmgr_pend_event(pfdctx, &timeout); testPrefixLogandCompare(prefixactualmsg[0]); iocLogPrefix(prefixstring); testPrefixLogandCompare(prefixactualmsg[1]); testPrefixLogandCompare(prefixactualmsg[2]); epicsSocketDestroy(sock); }
/* * RSRV_ONLINE_NOTIFY_TASK */ void rsrv_online_notify_task(void *pParm) { unsigned priorityOfSelf = epicsThreadGetPrioritySelf (); osiSockAddrNode *pNode; double delay; double maxdelay; long longStatus; double maxPeriod; caHdr msg; int status; SOCKET sock; int intTrue = TRUE; unsigned short port; ca_uint32_t beaconCounter = 0; char * pStr; int autoBeaconAddr; ELLLIST autoAddrList; char buf[16]; unsigned priorityOfUDP; epicsThreadBooleanStatus tbs; epicsThreadId tid; taskwdInsert (epicsThreadGetIdSelf(),NULL,NULL); if ( envGetConfigParamPtr ( & EPICS_CAS_BEACON_PERIOD ) ) { longStatus = envGetDoubleConfigParam ( & EPICS_CAS_BEACON_PERIOD, & maxPeriod ); } else { longStatus = envGetDoubleConfigParam ( & EPICS_CA_BEACON_PERIOD, & maxPeriod ); } if (longStatus || maxPeriod<=0.0) { maxPeriod = 15.0; epicsPrintf ("EPICS \"%s\" float fetch failed\n", EPICS_CAS_BEACON_PERIOD.name); epicsPrintf ("Setting \"%s\" = %f\n", EPICS_CAS_BEACON_PERIOD.name, maxPeriod); } delay = 0.02; /* initial beacon period in sec */ maxdelay = maxPeriod; /* * Open the socket. * Use ARPA Internet address format and datagram socket. * Format described in <sys/socket.h>. */ if ( (sock = epicsSocketCreate (AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) { errlogPrintf ("CAS: online socket creation error\n"); epicsThreadSuspendSelf (); } status = setsockopt (sock, SOL_SOCKET, SO_BROADCAST, (char *)&intTrue, sizeof(intTrue)); if (status<0) { errlogPrintf ("CAS: online socket set up error\n"); epicsThreadSuspendSelf (); } { /* * this connect is to supress a warning message on Linux * when we shutdown the read side of the socket. If it * fails (and it will on old ip kernels) we just ignore * the failure. */ osiSockAddr sockAddr; sockAddr.ia.sin_family = AF_UNSPEC; sockAddr.ia.sin_port = htons ( 0 ); sockAddr.ia.sin_addr.s_addr = htonl (0); connect ( sock, & sockAddr.sa, sizeof ( sockAddr.sa ) ); shutdown ( sock, SHUT_RD ); } memset((char *)&msg, 0, sizeof msg); msg.m_cmmd = htons (CA_PROTO_RSRV_IS_UP); msg.m_count = htons (ca_server_port); msg.m_dataType = htons (CA_MINOR_PROTOCOL_REVISION); ellInit ( & beaconAddrList ); ellInit ( & autoAddrList ); pStr = envGetConfigParam(&EPICS_CAS_AUTO_BEACON_ADDR_LIST, sizeof(buf), buf); if ( ! pStr ) { pStr = envGetConfigParam(&EPICS_CA_AUTO_ADDR_LIST, sizeof(buf), buf); } if (pStr) { if (strstr(pStr,"no")||strstr(pStr,"NO")) { autoBeaconAddr = FALSE; } else if (strstr(pStr,"yes")||strstr(pStr,"YES")) { autoBeaconAddr = TRUE; } else { fprintf(stderr, "CAS: EPICS_CA(S)_AUTO_ADDR_LIST = \"%s\"? Assuming \"YES\"\n", pStr); autoBeaconAddr = TRUE; } } else { autoBeaconAddr = TRUE; } /* * load user and auto configured * broadcast address list */ if (envGetConfigParamPtr(&EPICS_CAS_BEACON_PORT)) { port = envGetInetPortConfigParam (&EPICS_CAS_BEACON_PORT, (unsigned short) CA_REPEATER_PORT ); } else { port = envGetInetPortConfigParam (&EPICS_CA_REPEATER_PORT, (unsigned short) CA_REPEATER_PORT ); } /* * discover beacon addresses associated with this interface */ if ( autoBeaconAddr ) { osiSockAddr addr; ELLLIST tmpList; ellInit ( &tmpList ); addr.ia.sin_family = AF_UNSPEC; osiSockDiscoverBroadcastAddresses (&tmpList, sock, &addr); forcePort ( &tmpList, port ); removeDuplicateAddresses ( &autoAddrList, &tmpList, 1 ); } /* * by default use EPICS_CA_ADDR_LIST for the * beacon address list */ { const ENV_PARAM *pParam; if (envGetConfigParamPtr(&EPICS_CAS_INTF_ADDR_LIST) || envGetConfigParamPtr(&EPICS_CAS_BEACON_ADDR_LIST)) { pParam = &EPICS_CAS_BEACON_ADDR_LIST; } else { pParam = &EPICS_CA_ADDR_LIST; } /* * add in the configured addresses */ addAddrToChannelAccessAddressList ( &autoAddrList, pParam, port, pParam == &EPICS_CA_ADDR_LIST ); } removeDuplicateAddresses ( &beaconAddrList, &autoAddrList, 0 ); if ( ellCount ( &beaconAddrList ) == 0 ) { errlogPrintf ("The CA server's beacon address list was empty after initialization?\n"); } # ifdef DEBUG printChannelAccessAddressList (&beaconAddrList); # endif tbs = epicsThreadHighestPriorityLevelBelow ( priorityOfSelf, &priorityOfUDP ); if ( tbs != epicsThreadBooleanStatusSuccess ) { priorityOfUDP = priorityOfSelf; } casudp_startStopEvent = epicsEventMustCreate(epicsEventEmpty); casudp_ctl = ctlPause; tid = epicsThreadCreate ( "CAS-UDP", priorityOfUDP, epicsThreadGetStackSize (epicsThreadStackMedium), cast_server, 0 ); if ( tid == 0 ) { epicsPrintf ( "CAS: unable to start UDP daemon thread\n" ); } epicsEventMustWait(casudp_startStopEvent); epicsEventSignal(beacon_startStopEvent); while (TRUE) { pNode = (osiSockAddrNode *) ellFirst (&beaconAddrList); while (pNode) { char buf[64]; status = connect (sock, &pNode->addr.sa, sizeof(pNode->addr.sa)); if (status<0) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); ipAddrToDottedIP (&pNode->addr.ia, buf, sizeof(buf)); errlogPrintf ( "%s: CA beacon routing (connect to \"%s\") error was \"%s\"\n", __FILE__, buf, sockErrBuf); } else { struct sockaddr_in if_addr; osiSocklen_t size = sizeof (if_addr); status = getsockname (sock, (struct sockaddr *) &if_addr, &size); if (status<0) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); errlogPrintf ( "%s: CA beacon routing (getsockname) error was \"%s\"\n", __FILE__, sockErrBuf); } else if (if_addr.sin_family==AF_INET) { msg.m_available = if_addr.sin_addr.s_addr; msg.m_cid = htonl ( beaconCounter ); status = send (sock, (char *)&msg, sizeof(msg), 0); if (status < 0) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); ipAddrToDottedIP (&pNode->addr.ia, buf, sizeof(buf)); errlogPrintf ( "%s: CA beacon (send to \"%s\") error was \"%s\"\n", __FILE__, buf, sockErrBuf); } else { assert (status == sizeof(msg)); } } } pNode = (osiSockAddrNode *) pNode->node.next; } epicsThreadSleep(delay); if (delay<maxdelay) { delay *= 2.0; if (delay>maxdelay) { delay = maxdelay; } } beaconCounter++; /* expected to overflow */ while (beacon_ctl == ctlPause) { epicsThreadSleep(0.1); delay = 0.02; /* Restart beacon timing if paused */ } } }
int socketpair_compat(int af, int st, int p, SOCKET sd[2]) { SOCKET listener; int ret = -1; osiSockAddr ep[2]; osiSocklen_t slen = sizeof(ep[0]); if(st!=SOCK_STREAM) { SOCKERRNOSET(SOCK_EINVAL); return -1; } listener = epicsSocketCreate(AF_INET, SOCK_STREAM, 0); sd[0] = INVALID_SOCKET; sd[1] = shCreateSocket(AF_INET, SOCK_STREAM, 0); if(listener==INVALID_SOCKET || sd[1]==INVALID_SOCKET) { SOCKERRNOSET(SOCK_EMFILE); goto fail; } memset(ep, 0, sizeof(ep)); ep[0].ia.sin_family = AF_INET; ep[0].ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); if(bind(listener, &ep[0].sa, sizeof(ep[0]))) goto fail; if(getsockname(listener, &ep[0].sa, &slen)) goto fail; if(listen(listener, 2)) goto fail; /* we can't possibly succeed immediately */ if(connect(sd[1], &ep[0].sa, sizeof(ep[0]))!=-1) goto fail; if(SOCKERRNO!=SOCK_EINPROGRESS) goto fail; while(1) { int err; shSocket atemp; SOCKET temp; osiSocklen_t olen = sizeof(err); slen = sizeof(ep[1]); temp = epicsSocketAccept(listener, &ep[1].sa, &slen); if(temp==INVALID_SOCKET) { if(SOCKERRNO==SOCK_EINTR) continue; goto fail; } shSocketInit(&atemp); atemp.sd = sd[1]; if(shWaitFor(&atemp, SH_CANTX, 0)) { /* someone raced us and won... */ epicsSocketDestroy(temp); continue; } if(getsockopt(sd[1], SOL_SOCKET, SO_ERROR, (char*)&err, &olen)) goto fail; if(err) { SOCKERRNOSET(err); goto fail; } sd[0] = temp; break; } { /* restore blocking IO */ osiSockIoctl_t flag = 0; if(socket_ioctl(sd[1], FIONBIO, &flag)) goto fail; } epicsSocketDestroy(listener); return 0; fail: if(listener!=INVALID_SOCKET) epicsSocketDestroy(sd[0]); if(listener!=INVALID_SOCKET) epicsSocketDestroy(sd[0]); if(sd[1]!=INVALID_SOCKET) epicsSocketDestroy(sd[1]); return ret; }
void* module_data_parser_thread(void* arg){ int is_autocal_data, reg_data,i,j,k,code_depth,err; unsigned short *local_buffer_ptr,*temp_us_ptr,*conv,*process_buf_ptr,*netbuffer,frame_header[HEADER_LENGHT]; unsigned short packet_tag,slot_id=0; unsigned char th_dac=0,loop_mode=0; unsigned short this_frame_has_aligment_errors; SOCKET data_socket; struct sockaddr_in sock_addr; int status; local_buffer_ptr=databuffer_allocation(PIXIEII_MODULES*MATRIX_DIM_WORDS*15);//la dimensione in byte di un intero frame if(local_buffer_ptr==NULL){ printf("PROC:error allocating buffers\n"); exit(-1);} else{ if(verbose>=2)printf("PROC:Processing Thread Started\n"); } /***TCP/IP monitor***************inizio********************dacounting_daq.cpp********************/ sock_addr.sin_family=AF_INET; // indico il protocollo utilizzato (TCP/IP) sock_addr.sin_port=htons(4444); //indico la porta a cui connettere il socket if (hostToIPAddr("127.0.0.1", &sock_addr.sin_addr) < 0) printf("PROC:hostToIPAddr failed\n"); // The following is not supported on Linux. Is it needed? //sock_addr.sin_addr.S_un.S_un_b.s_b1=127; // indico l'indirizzo IP //sock_addr.sin_addr.S_un.S_un_b.s_b2=0; //sock_addr.sin_addr.S_un.S_un_b.s_b3=0; //sock_addr.sin_addr.S_un.S_un_b.s_b4=1; netbuffer=databuffer_allocation((MATRIX_DIM_WORDS*PIXIEII_MODULES)+HEADER_LENGHT); /*****TCP/IP monitor****************fine********************dacounting_daq.cpp********************/ printf("PROC:data Parser Thread started\n"); conv=conversion_table_allocation(); while(1){ status = epicsMessageQueueReceive(ptr_list, &process_buf_ptr, sizeof(&process_buf_ptr)); printf("module_data_parser_thread: got process_buf_ptr=%p\n", process_buf_ptr); if (status <= 0){ printf("PROC: error epicsMessageQueueReceive returned %d\n", status); continue; } if (process_buf_ptr==NULL){ printf("PROC: error process_buf_ptr=NULL\n"); continue; } packet_tag=*(process_buf_ptr+PACKET_TAG_OFFSET*2); th_dac=(packet_tag>>(PIXIE_THDAC_OFFSET+DUMMY_0_OFFSET))&PIXIE_THDAC_MASK; loop_mode=(packet_tag>>(LOOP_MODE_OFFSET+DUMMY_1_OFFSET))&LOOP_MODE_MASK; if(verbose>=2)printf("\nPROC: packet_tag=%04xh\n",packet_tag); if(verbose>=2)printf("\nPROC: th_dac=%d, loop_mode=%02Xh\n",th_dac,loop_mode); slot_id=*((char*)process_buf_ptr+SLOT_ID_OFFSET)&SLOT_ID_MASK; if(verbose>=2)printf("PROC: slot_id=%04xh\n",slot_id); if(packet_tag & AUTOCAL_DATA){ if(verbose>=2)printf("\nPROC:Autocal"); code_depth=5; is_autocal_data=1; } else{ if(verbose>=2)printf("\nPROC:Counters"); code_depth=15; is_autocal_data=0; } if(packet_tag & REG_PACKET){ if(verbose>=2)printf("\nPROC:REG 1 data\n"); reg_data=1; } else{ if(verbose>=2)printf("\nPROC:REG 0 data\n"); reg_data=0; } if(packet_tag & FRAME_HAS_ALIGN_ERRORS){ this_frame_has_aligment_errors=1; } else{ this_frame_has_aligment_errors=0; } temp_us_ptr=process_buf_ptr+(PACKET_TAG_BYTES/2); if(verbose>=3)printf("local_buffer filling code_depth=%d\n",code_depth); for(i=0;i<PIXIEII_MODULES;i++) { for(j=0;j<COLS_PER_DOUT*PIXIE_ROWS;j++) { for(k=0;k<code_depth;k++){ my_bytes_swap(temp_us_ptr+i+(j*PIXIEII_MODULES*code_depth)+(k*PIXIEII_MODULES)); local_buffer_ptr[(i*COLS_PER_DOUT*PIXIE_ROWS*code_depth)+(j*code_depth)+k]= temp_us_ptr[i+(j*PIXIEII_MODULES*code_depth)+(k*PIXIEII_MODULES)]; } } } //printf("local_buffer has been filled with original data and data modules are grouped\n"); //memcpy(buff+PACKET_TAG_BYTES,process_buf_ptr+PACKET_TAG_BYTES,PIXIEII_MODULES*MATRIX_DIM_WORDS*code_depth); for(i=0;i<PIXIEII_MODULES;i++){ //printf("parsing %d module data\n",i); for(j=0;j<COLS_PER_DOUT*PIXIE_ROWS;j++) { convert_bit_stream_to_counts(code_depth, local_buffer_ptr+(i*COLS_PER_DOUT*PIXIE_ROWS*code_depth)+(j*code_depth), process_buf_ptr+(i*MATRIX_DIM_WORDS)+(j*PIXIE_DOUTS)+(PACKET_TAG_BYTES/2),PIXIE_DOUTS); } } //printf("data parsed\n"); for(i=0;i<PIXIEII_MODULES;i++){ //printf("processing module %d data\n,i); if(is_autocal_data==0 && convert_data==1) decode_pixie_data_buffer(conv,process_buf_ptr+(PACKET_TAG_BYTES/2)+i*MATRIX_DIM_WORDS); databuffer_sorting(process_buf_ptr+(PACKET_TAG_BYTES/2)+i*MATRIX_DIM_WORDS); map_data_buffer_on_pixie(process_buf_ptr+(PACKET_TAG_BYTES/2)+i*MATRIX_DIM_WORDS); } /*********************sendig data to TCPIP monitor*********************/ for(i=0;i<HEADER_LENGHT;i++) frame_header[i]=0x8000; frame_header[0]=BUFFER_HDR_TAG; frame_header[1]|=(unsigned short)(this_frame_has_aligment_errors); frame_header[2]|=(unsigned short)(is_autocal_data); frame_header[3]|=(sh_code & 0x1); frame_header[4]|=(unsigned short)ceil((double)shutter_duration_ms); frame_header[5]|=(unsigned short)slot_id; if(reg_data==0) frame_header[6]|=REG_0_BUFF_CODE; else frame_header[6]|=REG_1_BUFF_CODE; for(i=0;i<HEADER_LENGHT;i++) netbuffer[i]=frame_header[i]; for(i=0;i<MATRIX_DIM_WORDS*PIXIEII_MODULES;i++) netbuffer[i+HEADER_LENGHT]=process_buf_ptr[i+(PACKET_TAG_BYTES/2)]; data_socket=epicsSocketCreate(PF_INET,SOCK_STREAM,0); err=connect(data_socket,(struct sockaddr*)&sock_addr,sizeof(struct sockaddr)); if(!err) { if (verbose>=1)printf("\r\nI got Pixie!!"); } else if (verbose>=1)printf("\r\nGot error attempting to connect to pixie = %s",strerror(errno)); if(!err) send(data_socket,(const char*)netbuffer,(MATRIX_DIM*PIXIEII_MODULES)+(HEADER_LENGHT*2),0); if(!err)epicsSocketDestroy(data_socket); /*********************sendig data to TCPIP monitor*********************/ free(process_buf_ptr); if (verbose>=1)printf("PROC:pocessing buffer released\n"); } free(local_buffer_ptr);//qui non ci arriverà mai!!!! }
int main(int argc, char**argv) { struct sockaddr_in si_me; struct sockaddr_in moderator_udp_sockaddr; unsigned short packet_tag; unsigned int i,j,temp_NPACK; SOCKET s, moderator_udp_sock_fd; int this_frame_has_aligment_errors=0; char temp_char; unsigned int packet_id, local_packet_id; long packet_id_gap; int received_data_subsets=0; moderation_type moderation=NOUDPMOD; clock_t timer_a=0,timer_b; double time_interval; char moderator_string[MAX_STRLEN]; id_mode packet_id_mode; ptr_list = epicsMessageQueueCreate(MAX_PENDING_BUFFERS, sizeof(unsigned char *)); if (ptr_list == 0) { printf("epicsMessageQueueCreate failed\n"); return -1; } if (osiSockAttach() == 0) { printf("osiSockAttach failed\n"); return -1; } if(argc==4){ if (strcmp(argv[3],"UDPMOD")==0) moderation=UDPMOD; else moderation=NOUDPMOD; verbose=atoi(argv[2]); if (strcmp(argv[1],"FRAG_ID")==0) packet_id_mode=FRAG_ID; else packet_id_mode=NOFRAG_ID; } if(argc==3){ verbose=atoi(argv[2]); if (strcmp(argv[1],"FRAG_ID")==0) packet_id_mode=FRAG_ID; else packet_id_mode=NOFRAG_ID; } else if(argc==2){ verbose=0; if (strcmp(argv[1],"FRAG_ID")==0) packet_id_mode=FRAG_ID; else packet_id_mode=NOFRAG_ID; } else{ verbose=0; packet_id_mode=FRAG_ID; moderation=NOUDPMOD; } buf=(unsigned char*)databuffer_allocation(MAX_PACK_LEN*DEFAULT_NPACK); if ((s=epicsSocketCreate(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) { printf("\r\nError creating socket error =%s", strerror(errno)); scanf("%c%*c",&temp_char); return 1; } memset((char *) &si_me, 0, sizeof(si_me)); si_me.sin_family = AF_INET; si_me.sin_port = htons(PORTA); si_me.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(s, (struct sockaddr *) &si_me, sizeof(si_me))==-1) { printf("\r\nError in binding data receiver socket"); //wait_akey(); return 1; } if ((moderator_udp_sock_fd=epicsSocketCreate(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) { printf("\r\nError creating moderator socket error =%s", strerror(errno)); scanf("%c%*c",&temp_char); return 1; } memset((char *) &moderator_udp_sockaddr, 0, sizeof(moderator_udp_sockaddr)); moderator_udp_sockaddr.sin_family = AF_INET; moderator_udp_sockaddr.sin_port = htons(MOD_UDP_REMOTE_PORT); // The following is not support on Linux. Is it needed? if (hostToIPAddr("192.168.0.255", &moderator_udp_sockaddr.sin_addr) < 0) printf("PROC:hostToIPAddr failed\n"); //moderator_udp_sockaddr.sin_addr.S_un.S_un_b.s_b1=192; //l'indirizzo IP!!! //moderator_udp_sockaddr.sin_addr.S_un.S_un_b.s_b2=168; //moderator_udp_sockaddr.sin_addr.S_un.S_un_b.s_b3=0; //moderator_udp_sockaddr.sin_addr.S_un.S_un_b.s_b4=255; int buffsize; osiSocklen_t czm = sizeof( int); int received_bytes; buffsize = MAXBUF; if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&buffsize, czm) != -1) { if(verbose>=2)printf("\r\nTrying to set Receive Buffer = %d", buffsize); } if (getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&buffsize, &czm) != -1) { if(verbose>=2)printf("\r\nReceive buffer is now = %d ", buffsize); if (buffsize == MAXBUF) { if(verbose>=2)printf("OK"); } else { if(verbose>=2)printf("ERROR Buffer Size too big!"); } } epicsThreadCreate("key_proc", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), (EPICSTHREADFUNC)key_proc, (void*)&i); epicsThreadCreate("module_data_parser_thread", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), (EPICSTHREADFUNC)module_data_parser_thread, NULL); while(looping){ // sem_wait(&(ptr_list.put_sem)); this_frame_has_aligment_errors=0; temp_NPACK=DEFAULT_NPACK; i=0; if(packet_id_mode==FRAG_ID){ while(i<temp_NPACK ){ j=0; while(j<DAQ_PACK_FRAGM){ received_bytes=recvfrom(s,(char*) buf+(i*MAX_PACK_LEN), MAX_PACK_LEN,0, NULL, 0); if (received_bytes== -1) printf("\rError receiveing datagram"); else if(received_bytes==MAX_PACK_LEN){ if(i==0) timer_a=clock(); received_packets++; packet_tag=*buf; if(packet_tag & AUTOCAL_DATA) temp_NPACK=AUTOCAL_NPACK; else temp_NPACK=DEFAULT_NPACK; /********************************************************************/; packet_id=buf[MAX_PACK_LEN*(i)+PACKET_ID_OFFSET]<<8; packet_id+=buf[MAX_PACK_LEN*(i)+1+PACKET_ID_OFFSET]; packet_id=packet_id%DAQ_PACK_FRAGM; packet_id_gap=(packet_id-j); if(packet_id_gap!=0){ if(id_error_packets<10) printf("ID: %d j= %d\n",packet_id,j); id_error_packets++; this_frame_has_aligment_errors=1; } if(packet_id_gap>=0){ j+=(packet_id_gap+1); i+=(packet_id_gap+1); } else{ j=DAQ_PACK_FRAGM; i+=DAQ_PACK_FRAGM; } } } if(moderation==UDPMOD){ sprintf(moderator_string,"DATASUBSET_RECEIVED %d %d\n",received_data_subsets,temp_NPACK/DAQ_PACK_FRAGM); received_data_subsets++; if (sendto(moderator_udp_sock_fd, moderator_string, strlen(moderator_string), 0, (struct sockaddr*)&moderator_udp_sockaddr, (osiSocklen_t)sizeof(moderator_udp_sockaddr))==-1) printf("\r\n!!Error sending moderating datagram!!"); } } } else{ while(i<temp_NPACK ){ received_bytes=recvfrom(s,(char*) buf+(i*MAX_PACK_LEN), MAX_PACK_LEN,0, NULL, 0); if (received_bytes== -1) printf("\rError receiveing datagram"); else if(received_bytes==MAX_PACK_LEN){ if(i==0) timer_a=clock(); //i++;j++; received_packets++; packet_tag=*buf; if(packet_tag & AUTOCAL_DATA) temp_NPACK=AUTOCAL_NPACK; else temp_NPACK=DEFAULT_NPACK; packet_id=buf[MAX_PACK_LEN*(i)+PACKET_ID_OFFSET]<<8; packet_id+=buf[MAX_PACK_LEN*(i)+1+PACKET_ID_OFFSET]; packet_id_gap=(packet_id-i);// if(packet_id_gap!=0){ id_error_packets++; this_frame_has_aligment_errors=1; } if(packet_id_gap>=0){ i+=(packet_id_gap+1); } else{ i=temp_NPACK; } if((i%DAQ_PACK_FRAGM)==0 && i!=0 && moderation==UDPMOD){ sprintf(moderator_string,"DATASUBSET_RECEIVED %d %d\n",received_data_subsets,temp_NPACK/DAQ_PACK_FRAGM); received_data_subsets++; if (sendto(moderator_udp_sock_fd, moderator_string, strlen(moderator_string), 0, (struct sockaddr*)&moderator_udp_sockaddr, sizeof(moderator_udp_sockaddr))==-1) printf("\r\n!!Error sending moderating datagram!!"); } } } } received_data_subsets=0; if(verbose>=1){ timer_b=clock(); time_interval=(double)(timer_b-timer_a)/CLOCKS_PER_SEC; printf("MAIN:%d packets(%d bytes each) have been received in %.3f s ",i,MAX_PACK_LEN,time_interval); printf("(%.3f Mbps)\n",(i*MAX_PACK_LEN*8)/(time_interval*1024*1024)); } i=0; local_packet_id=0; process_buf=(unsigned char*)databuffer_allocation((MAX_PACK_LEN-PACKET_EXTRA_BYTES+PACKET_TAG_BYTES)*DEFAULT_NPACK); if((buf==NULL)||(process_buf==NULL)){ printf("error allocating buffers\n"); exit(0); } else if(verbose>=1) printf("MAIN:New Processing Buffer Allocated\n"); while((i<temp_NPACK)) { memcpy(process_buf+PACKET_TAG_BYTES+(PACKET_SENSOR_DATA_BYTES*local_packet_id), buf+PACKET_SENSOR_DATA_OFFSET+(MAX_PACK_LEN*i), PACKET_SENSOR_DATA_BYTES); for(j=0;j<PACKET_TAG_BYTES;j++) process_buf[PACKET_TAG_OFFSET+j]=buf[j];//copio il PACKET_TAG del buffer per processing if(this_frame_has_aligment_errors) process_buf[PACKET_TAG_OFFSET]|=FRAME_HAS_ALIGN_ERRORS; else process_buf[PACKET_TAG_OFFSET]&=(~FRAME_HAS_ALIGN_ERRORS); local_packet_id++; i++; } printf("Main: sending process_buf=%p\n", process_buf); epicsMessageQueueSend(ptr_list, &process_buf, sizeof(&process_buf)); } free(buf); free(process_buf); scanf("%c%*c",&temp_char); return EXIT_SUCCESS; }
/* * * main() * */ int main(void) { struct sockaddr_in serverAddr; /* server's address */ struct timeval timeout; int status; struct ioc_log_server *pserver; osiSockIoctl_t optval; status = getConfig(); if (status<0) { fprintf(stderr, "iocLogServer: EPICS environment underspecified\n"); fprintf(stderr, "iocLogServer: failed to initialize\n"); return IOCLS_ERROR; } pserver = (struct ioc_log_server *) calloc(1, sizeof *pserver); if (!pserver) { fprintf(stderr, "iocLogServer: %s\n", strerror(errno)); return IOCLS_ERROR; } pserver->pfdctx = (void *) fdmgr_init(); if (!pserver->pfdctx) { fprintf(stderr, "iocLogServer: %s\n", strerror(errno)); return IOCLS_ERROR; } /* * Open the socket. Use ARPA Internet address format and stream * sockets. Format described in <sys/socket.h>. */ pserver->sock = epicsSocketCreate(AF_INET, SOCK_STREAM, 0); if (pserver->sock == INVALID_SOCKET) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf(stderr, "iocLogServer: sock create err: %s\n", sockErrBuf); free(pserver); return IOCLS_ERROR; } epicsSocketEnableAddressReuseDuringTimeWaitState ( pserver->sock ); /* Zero the sock_addr structure */ memset((void *)&serverAddr, 0, sizeof serverAddr); serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(ioc_log_port); /* get server's Internet address */ status = bind ( pserver->sock, (struct sockaddr *)&serverAddr, sizeof (serverAddr) ); if (status < 0) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf(stderr, "iocLogServer: bind err: %s\n", sockErrBuf ); fprintf (stderr, "iocLogServer: a server is already installed on port %u?\n", (unsigned)ioc_log_port); return IOCLS_ERROR; } /* listen and accept new connections */ status = listen(pserver->sock, 10); if (status < 0) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf(stderr, "iocLogServer: listen err %s\n", sockErrBuf); return IOCLS_ERROR; } /* * Set non blocking IO * to prevent dead locks */ optval = TRUE; status = socket_ioctl( pserver->sock, FIONBIO, &optval); if (status < 0){ char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf(stderr, "iocLogServer: ioctl FIONBIO err %s\n", sockErrBuf); return IOCLS_ERROR; } # ifdef UNIX status = setupSIGHUP(pserver); if (status < 0) { return IOCLS_ERROR; } # endif status = openLogFile(pserver); if (status < 0) { fprintf(stderr, "File access problems to `%s' because `%s'\n", ioc_log_file_name, strerror(errno)); return IOCLS_ERROR; } status = fdmgr_add_callback( pserver->pfdctx, pserver->sock, fdi_read, acceptNewClient, pserver); if (status < 0) { fprintf(stderr, "iocLogServer: failed to add read callback\n"); return IOCLS_ERROR; } while (TRUE) { timeout.tv_sec = 60; /* 1 min */ timeout.tv_usec = 0; fdmgr_pend_event(pserver->pfdctx, &timeout); fflush(pserver->poutfile); } }
// // udpiiu::udpiiu () // udpiiu::udpiiu ( epicsGuard < epicsMutex > & cacGuard, epicsTimerQueueActive & timerQueue, epicsMutex & cbMutexIn, epicsMutex & cacMutexIn, cacContextNotify & ctxNotifyIn, cac & cac, unsigned port, tsDLList < SearchDest > & searchDestListIn ) : recvThread ( *this, ctxNotifyIn, cbMutexIn, "CAC-UDP", epicsThreadGetStackSize ( epicsThreadStackMedium ), cac::lowestPriorityLevelAbove ( cac::lowestPriorityLevelAbove ( cac.getInitializingThreadsPriority () ) ) ), m_repeaterTimerNotify ( *this ), repeaterSubscribeTmr ( m_repeaterTimerNotify, timerQueue, cbMutexIn, ctxNotifyIn ), govTmr ( *this, timerQueue, cacMutexIn ), maxPeriod ( maxSearchPeriodDefault ), rtteMean ( minRoundTripEstimate ), rtteMeanDev ( 0 ), cacRef ( cac ), cbMutex ( cbMutexIn ), cacMutex ( cacMutexIn ), nBytesInXmitBuf ( 0 ), nTimers ( 0 ), beaconAnomalyTimerIndex ( 0 ), sequenceNumber ( 0 ), lastReceivedSeqNo ( 0 ), sock ( 0 ), repeaterPort ( 0 ), serverPort ( port ), localPort ( 0 ), shutdownCmd ( false ), lastReceivedSeqNoIsValid ( false ) { cacGuard.assertIdenticalMutex ( cacMutex ); if ( envGetConfigParamPtr ( & EPICS_CA_MAX_SEARCH_PERIOD ) ) { long longStatus = envGetDoubleConfigParam ( & EPICS_CA_MAX_SEARCH_PERIOD, & this->maxPeriod ); if ( ! longStatus ) { if ( this->maxPeriod < maxSearchPeriodLowerLimit ) { epicsPrintf ( "\"%s\" out of range (low)\n", EPICS_CA_MAX_SEARCH_PERIOD.name ); this->maxPeriod = maxSearchPeriodLowerLimit; epicsPrintf ( "Setting \"%s\" = %f seconds\n", EPICS_CA_MAX_SEARCH_PERIOD.name, this->maxPeriod ); } } else { epicsPrintf ( "EPICS \"%s\" wasnt a real number\n", EPICS_CA_MAX_SEARCH_PERIOD.name ); epicsPrintf ( "Setting \"%s\" = %f seconds\n", EPICS_CA_MAX_SEARCH_PERIOD.name, this->maxPeriod ); } } double powerOfTwo = log ( this->maxPeriod / minRoundTripEstimate ) / log ( 2.0 ); this->nTimers = static_cast < unsigned > ( powerOfTwo + 1.0 ); if ( this->nTimers > channelNode::getMaxSearchTimerCount () ) { this->nTimers = channelNode::getMaxSearchTimerCount (); epicsPrintf ( "\"%s\" out of range (high)\n", EPICS_CA_MAX_SEARCH_PERIOD.name ); epicsPrintf ( "Setting \"%s\" = %f seconds\n", EPICS_CA_MAX_SEARCH_PERIOD.name, (1<<(this->nTimers-1)) * minRoundTripEstimate ); } powerOfTwo = log ( beaconAnomalySearchPeriod / minRoundTripEstimate ) / log ( 2.0 ); this->beaconAnomalyTimerIndex = static_cast < unsigned > ( powerOfTwo + 1.0 ); if ( this->beaconAnomalyTimerIndex >= this->nTimers ) { this->beaconAnomalyTimerIndex = this->nTimers - 1; } this->ppSearchTmr.reset ( new epics_auto_ptr < class searchTimer > [ this->nTimers ] ); for ( unsigned i = 0; i < this->nTimers; i++ ) { this->ppSearchTmr[i].reset ( new searchTimer ( *this, timerQueue, i, cacMutexIn, i > this->beaconAnomalyTimerIndex ) ); } this->repeaterPort = envGetInetPortConfigParam ( &EPICS_CA_REPEATER_PORT, static_cast <unsigned short> (CA_REPEATER_PORT) ); this->sock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); if ( this->sock == INVALID_SOCKET ) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); errlogPrintf ("CAC: unable to create datagram socket because = \"%s\"\n", sockErrBuf ); throwWithLocation ( noSocket () ); } int boolValue = true; int status = setsockopt ( this->sock, SOL_SOCKET, SO_BROADCAST, (char *) &boolValue, sizeof ( boolValue ) ); if ( status < 0 ) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); errlogPrintf ("CAC: IP broadcasting enable failed because = \"%s\"\n", sockErrBuf ); } #if 0 { /* * some concern that vxWorks will run out of mBuf's * if this change is made joh 11-10-98 * * bump up the UDP recv buffer */ int size = 1u<<15u; status = setsockopt ( this->sock, SOL_SOCKET, SO_RCVBUF, (char *)&size, sizeof (size) ); if (status<0) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); errlogPrintf ( "CAC: unable to set socket option SO_RCVBUF because \"%s\"\n", sockErrBuf ); } } #endif // force a bind to an unconstrained address so we can obtain // the local port number below static const unsigned short PORT_ANY = 0u; osiSockAddr addr; memset ( (char *)&addr, 0 , sizeof (addr) ); addr.ia.sin_family = AF_INET; addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY ); addr.ia.sin_port = htons ( PORT_ANY ); status = bind (this->sock, &addr.sa, sizeof (addr) ); if ( status < 0 ) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); epicsSocketDestroy (this->sock); errlogPrintf ( "CAC: unable to bind to an unconstrained address because = \"%s\"\n", sockErrBuf ); throwWithLocation ( noSocket () ); } { osiSockAddr tmpAddr; osiSocklen_t saddr_length = sizeof ( tmpAddr ); status = getsockname ( this->sock, &tmpAddr.sa, &saddr_length ); if ( status < 0 ) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); epicsSocketDestroy ( this->sock ); errlogPrintf ( "CAC: getsockname () error was \"%s\"\n", sockErrBuf ); throwWithLocation ( noSocket () ); } if ( tmpAddr.sa.sa_family != AF_INET) { epicsSocketDestroy ( this->sock ); errlogPrintf ( "CAC: UDP socket was not inet addr family\n" ); throwWithLocation ( noSocket () ); } this->localPort = ntohs ( tmpAddr.ia.sin_port ); } /* * load user and auto configured * broadcast address list */ ELLLIST dest; ellInit ( & dest ); configureChannelAccessAddressList ( & dest, this->sock, this->serverPort ); while ( osiSockAddrNode * pNode = reinterpret_cast < osiSockAddrNode * > ( ellGet ( & dest ) ) ) { SearchDestUDP & searchDest = * new SearchDestUDP ( pNode->addr, *this ); _searchDestList.add ( searchDest ); free ( pNode ); } /* add list of tcp name service addresses */ _searchDestList.add ( searchDestListIn ); caStartRepeaterIfNotInstalled ( this->repeaterPort ); this->pushVersionMsg (); // start timers and receive thread for ( unsigned j =0; j < this->nTimers; j++ ) { this->ppSearchTmr[j]->start ( cacGuard ); } this->govTmr.start (); this->repeaterSubscribeTmr.start (); this->recvThread.start (); }