static socket_udp *udp_init6(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl) { #ifdef HAVE_IPv6 int reuse = 1; struct sockaddr_in6 s_in; socket_udp *s = (socket_udp *) malloc(sizeof(socket_udp)); s->mode = IPv6; s->addr = NULL; s->rx_port = rx_port; s->tx_port = tx_port; s->ttl = ttl; if (iface != NULL) { debug_msg("Not yet implemented\n"); abort(); } if (inet_pton(AF_INET6, addr, &s->addr6) != 1) { /* We should probably try to do a DNS lookup on the name */ /* here, but I'm trying to get the basics going first... */ debug_msg("IPv6 address conversion failed\n"); free(s); return NULL; } s->fd = socket(AF_INET6, SOCK_DGRAM, 0); if (s->fd < 0) { socket_error("socket"); return NULL; } if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) != 0) { socket_error("setsockopt SO_REUSEADDR"); return NULL; } #ifdef SO_REUSEPORT if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEPORT, (char *) &reuse, sizeof(reuse)) != 0) { socket_error("setsockopt SO_REUSEPORT"); return NULL; } #endif memset((char *)&s_in, 0, sizeof(s_in)); s_in.sin6_family = AF_INET6; s_in.sin6_port = htons(rx_port); #ifdef HAVE_SIN6_LEN s_in.sin6_len = sizeof(s_in); #endif s_in.sin6_addr = in6addr_any; if (bind(s->fd, (struct sockaddr *) &s_in, sizeof(s_in)) != 0) { socket_error("bind"); return NULL; } if (IN6_IS_ADDR_MULTICAST(&(s->addr6))) { unsigned int loop = 1; struct ipv6_mreq imr; #ifdef MUSICA_IPV6 imr.i6mr_interface = 1; imr.i6mr_multiaddr = s->addr6; #else imr.ipv6mr_multiaddr = s->addr6; imr.ipv6mr_interface = 0; #endif if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *) &imr, sizeof(imr)) != 0) { socket_error("setsockopt IPV6_ADD_MEMBERSHIP"); return NULL; } if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *) &loop, sizeof(loop)) != 0) { socket_error("setsockopt IPV6_MULTICAST_LOOP"); return NULL; } if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &ttl, sizeof(ttl)) != 0) { socket_error("setsockopt IPV6_MULTICAST_HOPS"); return NULL; } } ASSERT(s != NULL); s->addr = strdup(addr); return s; #else UNUSED(addr); UNUSED(iface); UNUSED(rx_port); UNUSED(tx_port); UNUSED(ttl); return NULL; #endif }
//------------------------------------------------------------------------------ // // Listen() - // //------------------------------------------------------------------------------ bool CPassiveSocket::Listen(const uint8 *pAddr, int16 nPort, int32 nConnectionBacklog) { bool bRetVal = false; #ifdef WIN32 ULONG inAddr; #else int32 nReuse; in_addr_t inAddr; nReuse = IPTOS_LOWDELAY; #endif //-------------------------------------------------------------------------- // Set the following socket options SO_REUSEADDR, SO_LINGER, this will // allow the file descriptor to be reused immediately after the socket is // closed instead of setting in a TIMED_WAIT state. //-------------------------------------------------------------------------- #ifdef _LINUX SETSOCKOPT(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&nReuse, sizeof(int32)); SETSOCKOPT(m_socket, IPPROTO_TCP, IP_TOS, &nReuse, sizeof(int32)); #endif memset(&m_stServerSockaddr,0,sizeof(m_stServerSockaddr)); m_stServerSockaddr.sin_family = AF_INET; m_stServerSockaddr.sin_port = htons(nPort); //-------------------------------------------------------------------------- // If no IP Address (interface ethn) is supplied, or the loop back is // specified then bind to any interface, else bind to specified interface. //-------------------------------------------------------------------------- if ((pAddr == NULL) || (!strlen((const char *)pAddr))) { m_stServerSockaddr.sin_addr.s_addr = htonl(INADDR_ANY); } else { if ((inAddr = inet_addr((const char *)pAddr)) != INADDR_NONE) { m_stServerSockaddr.sin_addr.s_addr = inAddr; } } m_timer.Initialize(); m_timer.SetStartTime(); //-------------------------------------------------------------------------- // Bind to the specified port //-------------------------------------------------------------------------- if (bind(m_socket, (struct sockaddr *)&m_stServerSockaddr, sizeof(m_stServerSockaddr)) != CSimpleSocket::SocketError) { if (m_nSocketType == CSimpleSocket::SocketTypeTcp) { if (listen(m_socket, nConnectionBacklog) != CSimpleSocket::SocketError) { m_timer.SetEndTime(); bRetVal = true; } } else { bRetVal = true; } } //-------------------------------------------------------------------------- // If there was a socket error then close the socket to clean out the // connection in the backlog. //-------------------------------------------------------------------------- TranslateSocketError(); if (bRetVal == false) { Close(); } return bRetVal; }
int respond(int connfd, size_t port, FILE *logfile, int *tcpquickack) { struct setup_header setupBuffer; size_t bytesRead = 0, requestCount = 0, bytesWritten = 0, responseCount = 0, qh = 0, qt = 0; ssize_t n; uint64_t readEnd, writeEnd; struct request_header *requestBuffer; struct response_header *responseBuffer; struct request *requests; fd_set rfds, wfds; n = read(connfd, &setupBuffer, sizeof(struct setup_header)); readEnd = microseconds(); if (n != sizeof(struct setup_header)) { fprintf(stderr, "Failed to read setup from connection on port %lu\n", port); return -1; } write(connfd, &readEnd, sizeof(uint64_t)); LOGF(logfile, LOG_LEVEL_L, "client %lu sending %lu requests of size %lu expecting responses of size %lu\n", port, setupBuffer.requests, setupBuffer.request_size, setupBuffer.response_size); LOGSOCKOPT(logfile, LOG_LEVEL_L, connfd, IPPROTO_TCP, TCP_QUICKACK); LOGSOCKOPT(logfile, LOG_LEVEL_L, connfd, IPPROTO_TCP, TCP_NODELAY); requestBuffer = malloc(setupBuffer.request_size); responseBuffer = malloc(setupBuffer.response_size); requests = calloc(setupBuffer.simul + 1, sizeof(struct request)); memset(responseBuffer, 0xA0, setupBuffer.response_size); responseBuffer->prev_seq = 0; responseBuffer->prev_index = 0; responseBuffer->prev_write_end = microseconds(); while (!setupBuffer.requests || responseCount < setupBuffer.requests) { FD_ZERO(&rfds); if (!setupBuffer.requests || requestCount < setupBuffer.requests) { FD_SET(connfd, &rfds); } FD_ZERO(&wfds); if (responseCount < requestCount) { FD_SET(connfd, &wfds); } LOGSOCKOPT(logfile, LOG_LEVEL_V, connfd, IPPROTO_TCP, TCP_NODELAY); LOGSOCKOPT(logfile, LOG_LEVEL_V, connfd, IPPROTO_TCP, TCP_QUICKACK); LOGF(logfile, LOG_LEVEL_V, "selecting requests, %lu requests recieved %lu responses written\n", requestCount, responseCount); select(connfd+1, &rfds, &wfds, NULL, NULL); if (FD_ISSET(connfd, &rfds)) { LOGF(logfile, LOG_LEVEL_V, "reading %ld bytes from port %lu\n", setupBuffer.request_size - bytesRead, port); if (bytesRead == 0) { requests[qt].request_read_start = microseconds(); } n = read(connfd, ((char*)requestBuffer) + bytesRead, setupBuffer.request_size - bytesRead); requests[qt].request_read_end = microseconds(); if (n < 0) { perror("read: "); fprintf(stderr, "Failed to read request from connection on port %lu\n", port); return -1; } if (n == 0) { fprintf(stderr, "Connection on port %lu closed during read\n", port); return -1; } LOGF(logfile, LOG_LEVEL_V, "read %lu bytes from port %lu\n", n, port); bytesRead +=n; if (bytesRead == setupBuffer.request_size) { requests[qt].seq = requestBuffer->seq; requests[qt].index = requestBuffer->index; LOGF(logfile, LOG_LEVEL_V, "finished read from port %lu saved %lu, %lu, %lu, %lu at %lu to index %lu\n", port, requests[qt].seq, requests[qt].request_rcvd, requests[qt].request_read_start, requests[qt].request_read_end, requests[qt].index, qt); qt = (qt + 1) % (setupBuffer.simul + 1); ++requestCount; bytesRead = 0; } } if (FD_ISSET(connfd, &wfds)) { if (bytesWritten == 0) { responseBuffer->seq = requests[qh].seq; responseBuffer->index = requests[qh].index; responseBuffer->rcvd = requests[qh].request_rcvd; responseBuffer->read_start = requests[qh].request_read_start; responseBuffer->read_end = requests[qh].request_read_end; responseBuffer->write_start = microseconds(); LOGF(logfile, LOG_LEVEL_V, "starting write to port %lu for %lu reading from index %lu to index %lu (previous index %lu)\n", port, responseBuffer->seq, qh, responseBuffer->index, responseBuffer->prev_index); } n = write(connfd, ((char*)responseBuffer) + bytesWritten, setupBuffer.response_size - bytesWritten); writeEnd = microseconds(); SETSOCKOPT(logfile, LOG_LEVEL_V, connfd, IPPROTO_TCP, TCP_QUICKACK, tcpquickack); if (n < 0) { perror("write: "); fprintf(stderr, "Failed to write request to connection on port %lu\n", port); return -1; } if (n == 0) { fprintf(stderr, "Connection on port %lu closed during write\n", port); return -1; } LOGF(logfile, LOG_LEVEL_V, "wrote %lu bytes to port %lu\n", n, port); bytesWritten += n; if (bytesWritten == setupBuffer.response_size) { responseBuffer->prev_seq = responseBuffer->seq; responseBuffer->prev_index = responseBuffer->index; responseBuffer->prev_write_end = writeEnd; qh = (qh + 1) % (setupBuffer.simul + 1); ++responseCount; bytesWritten = 0; } } } free(requestBuffer); free(responseBuffer); free(requests); return 0; }
static socket_udp *udp_init4(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl) { int reuse = 1; struct sockaddr_in s_in; int recv_buf_size; int test_buffer; int test_buffer_size=sizeof(test_buffer); socket_udp *s = (socket_udp *)malloc(sizeof(socket_udp)); s->mode = IPv4; s->addr = NULL; s->rx_port = rx_port; s->tx_port = tx_port; s->ttl = ttl; if (inet_pton(AF_INET, addr, &s->addr4) != 1) { struct hostent *h = gethostbyname(addr); if (h == NULL) { socket_error("Can't resolve IP address for %s", addr); free(s); return NULL; } memcpy(&(s->addr4), h->h_addr_list[0], sizeof(s->addr4)); } if (iface != NULL) { if (inet_pton(AF_INET, iface, &s->iface4_addr) != 1) { rtp_message(LOG_ERR, "Illegal interface specification"); free(s); return NULL; } } else { s->iface4_addr.s_addr = 0; } s->fd = socket(AF_INET, SOCK_DGRAM, 0); if (s->fd < 0) { socket_error("socket"); free(s); return NULL; } if (have_recv_buf_size != 0) { recv_buf_size = recv_buf_size_value; if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_RCVBUF, (char *)&recv_buf_size, sizeof(int)) != 0) { socket_error("setsockopt SO_RCVBUF"); close(s->fd); free(s); return NULL; } //Since setsockopt would not return the error if /proc/sys/net/core/rmem_max is smaller //then the value you are trying to set. use sysctl -w net.core.rmem_max=new_val //to set the value higher than what is desired in RCVBUF if( getsockopt( s->fd, SOL_SOCKET, SO_RCVBUF, (void*)&test_buffer, &test_buffer_size ) == -1 ) { socket_error("getsockopt SO_RCVBUF"); } else { //See if we could set the desired value if(test_buffer < recv_buf_size) { rtp_message(LOG_WARNING, "Failed to set the RCVBUF to %d, only could set %d\n. Check the Max kernel receive buffer size using \"sysctl net.core.rmem_max\"\n", recv_buf_size, test_buffer); } } } if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) != 0) { socket_error("setsockopt SO_REUSEADDR"); close(s->fd); free(s); return NULL; } #ifdef SO_REUSEPORT if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEPORT, (char *) &reuse, sizeof(reuse)) != 0) { close(s->fd); free(s); socket_error("setsockopt SO_REUSEPORT"); return NULL; } #endif s_in.sin_family = AF_INET; s_in.sin_addr.s_addr = INADDR_ANY; s_in.sin_port = htons(rx_port); if (bind(s->fd, (struct sockaddr *) &s_in, sizeof(s_in)) != 0) { socket_error("bind: port %d", rx_port); close(s->fd); free(s); return NULL; } if (IN_MULTICAST(ntohl(s->addr4.s_addr))) { char loop = 1; #ifndef HAVE_IGMP_V3 struct ip_mreq imr; imr.imr_multiaddr.s_addr = s->addr4.s_addr; imr.imr_interface.s_addr = s->iface4_addr.s_addr; if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &imr, sizeof(struct ip_mreq)) != 0) { socket_error("setsockopt IP_ADD_MEMBERSHIP"); close(s->fd); free(s); return NULL; } #else rtp_message(LOG_DEBUG,"IGMPV3 src:%s\n", G_Multicast_Src); /* Join Multicast group with source filter */ if (G_IGMP_V3 != 0 && strcmp(G_Multicast_Src, "0.0.0.0") != 0) { struct ip_mreq_source imr; imr.imr_multiaddr.s_addr = s->addr4.s_addr; imr.imr_interface.s_addr = s->iface4_addr.s_addr; if (inet_aton(G_Multicast_Src, &imr.imr_sourceaddr) == 0) { rtp_message(LOG_ERR, "inet_aton failed for %s\n", G_Multicast_Src); return NULL; } if( setsockopt( s->fd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (char*)&imr, sizeof(struct ip_mreq_source) ) == -1 ) { socket_error("setsockopt IP_ADD_SOURCE_MEMBERSHIP"); close(s->fd); free(s); return NULL; } } #endif #ifndef WIN32 if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) != 0) { socket_error("setsockopt IP_MULTICAST_LOOP"); close(s->fd); free(s); return NULL; } #endif if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &s->ttl, sizeof(s->ttl)) != 0) { socket_error("setsockopt IP_MULTICAST_TTL"); close(s->fd); free(s); return NULL; } if (s->iface4_addr.s_addr != 0) { if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_IF, (char *) &s->iface4_addr, sizeof(s->iface4_addr)) != 0) { close(s->fd); free(s); socket_error("setsockopt IP_MULTICAST_IF"); return NULL; } } } s->addr = strdup(addr); return s; }
/* driver function */ int main(int argc, char **argv) { char hostaddr[MAXLINE], hostname[MAXLINE], *progname = argv[0], *portstring; int listenfd, connfd, error, pid, threaded = 0; size_t port, total = 0; FILE *logfile = NULL; sem_t count; struct options options; pthread_t cleaning; socklen_t clientlen; union { struct sockaddr_in client4; struct sockaddr_in6 client6; } clientaddr; if (sem_init(&count, 0, 0) == -1 || pthread_create(&cleaning, NULL, clean, &count) != 0) { perror(NULL); fprintf(stderr, "Warning : Unable to initialize thread mechanisms, child processes may not be cleaned up\n"); } else { threaded = 1; } memset(&options, 0, sizeof(struct options)); options.argc = argc - 1; options.argv = argv + 1; options.log_level = &log_level; error = optparse(&options); if (error || options.argc != 1) { fprintf(stderr, usage, progname); return error ? error - 1 : 0; } if (options.logfilename) { logfile = fopen(options.logfilename, "a"); } portstring = options.argv[0]; listenfd = open_socketfd(NULL, portstring, AI_PASSIVE, SOCK_STREAM, &bind); if(listenfd < 0) { fprintf(stderr, "Error : Cannot listen to socket %s with error %d\n", portstring, listenfd); return 1; } SETSOCKOPT(logfile, LOG_LEVEL_V, listenfd, SOL_SOCKET, SO_REUSEADDR, &option_true); SETSOCKOPT(logfile, LOG_LEVEL_L, listenfd, SOL_SOCKET, SO_PRIORITY, options.sopriority); SETSOCKOPT(logfile, LOG_LEVEL_L, listenfd, IPPROTO_TCP, TCP_NODELAY, options.tcpnodelay); SETSOCKOPT(logfile, LOG_LEVEL_L, listenfd, IPPROTO_TCP, TCP_QUICKACK, options.tcpquickack); if (listen(listenfd, LISTEN_MAX) == -1) { fprintf(stderr, "Error : Cannot listen on port\n"); return 1; } LOG(logfile, LOG_LEVEL_L, "listening\n"); while(1) { clientlen = sizeof(clientaddr); connfd = accept(listenfd, (void *)(&clientaddr), &clientlen); if (connfd == -1) { continue; } LOGSOCKOPT(logfile, LOG_LEVEL_L, connfd, SOL_SOCKET, SO_PRIORITY); LOGSOCKOPT(logfile, LOG_LEVEL_L, connfd, IPPROTO_TCP, TCP_NODELAY); LOGSOCKOPT(logfile, LOG_LEVEL_L, connfd, IPPROTO_TCP, TCP_QUICKACK); error = getnameinfo((struct sockaddr*)&clientaddr, clientlen, hostname, sizeof(hostname), NULL, 0, 0); if (error != 0) { close(connfd); continue; } error = getnameinfo((struct sockaddr*)&clientaddr, clientlen, hostaddr, sizeof(hostaddr), NULL, 0, NI_NUMERICHOST); port = ntohs(((struct sockaddr*)&clientaddr)->sa_family == AF_INET ? ((struct sockaddr_in*)&clientaddr)->sin_port : ((struct sockaddr_in6*)&clientaddr)->sin6_port); if (error) { LOGF(logfile, LOG_LEVEL_L, "connected to %s : %lu\n", hostname, port); } else { LOGF(logfile, LOG_LEVEL_L, "connected to %s (%s) : %lu\n", hostname, hostaddr, port); } if ((pid = fork()) == 0) { close(listenfd); respond(connfd, port, logfile, options.tcpquickack); LOGF(logfile, LOG_LEVEL_L, "server: closing connection to %s (%s) : %lu\n", hostname, hostaddr, port); if (logfile) { fclose(logfile); } close(connfd); exit(0); } ++total; close(connfd); if (pid > 0) { if (threaded && sem_post(&count) == -1) { fprintf(stderr, "Warning : Semaphore overflow, child processes may not be cleaned up\n"); } LOGF(logfile, LOG_LEVEL_L, "server: forked to pid %d, connection accepted\n", pid); } if(pid == -1) { fprintf(stderr, "Error : Failed to fork, connection refused\n"); } } }
/** Basic setup to connect NIC to socket. * @param[in] port = port context struct * @param[in] ifname = Name of NIC device, f.e. "eth0" * @param[in] secondary = if >0 then use secondary stack instead of primary * @return >0 if succeeded */ int ecx_setupnic(ecx_portt *port, const char *ifname, int secondary) { int i; int r, rval, ifindex; struct timeval timeout; struct ifreq ifr; struct sockaddr_ll sll; int *psock; rval = 0; if (secondary) { /* secondary port stuct available? */ if (port->redport) { /* when using secondary socket it is automatically a redundant setup */ psock = &(port->redport->sockhandle); *psock = -1; port->redstate = ECT_RED_DOUBLE; port->redport->stack.sock = &(port->redport->sockhandle); port->redport->stack.txbuf = &(port->txbuf); port->redport->stack.txbuflength = &(port->txbuflength); port->redport->stack.tempbuf = &(port->redport->tempinbuf); port->redport->stack.rxbuf = &(port->redport->rxbuf); port->redport->stack.rxbufstat = &(port->redport->rxbufstat); port->redport->stack.rxsa = &(port->redport->rxsa); } else { /* fail */ return 0; } } else { rt_mutex_create(&port->getindex_mutex, "getindex_mutex"); rt_mutex_create(&port->tx_mutex, "tx_mutex"); rt_mutex_create(&port->rx_mutex, "rx_mutex"); port->sockhandle = -1; port->lastidx = 0; port->redstate = ECT_RED_NONE; port->stack.sock = &(port->sockhandle); port->stack.txbuf = &(port->txbuf); port->stack.txbuflength = &(port->txbuflength); port->stack.tempbuf = &(port->tempinbuf); port->stack.rxbuf = &(port->rxbuf); port->stack.rxbufstat = &(port->rxbufstat); port->stack.rxsa = &(port->rxsa); psock = &(port->sockhandle); } /* we use RAW packet socket, with packet type ETH_P_ECAT */ *psock = SOCKET(PF_PACKET, SOCK_RAW, htons(ETH_P_ECAT)); timeout.tv_sec = 0; timeout.tv_usec = 1; r = SETSOCKOPT(*psock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); r = SETSOCKOPT(*psock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); i = 1; r = SETSOCKOPT(*psock, SOL_SOCKET, SO_DONTROUTE, &i, sizeof(i)); /* connect socket to NIC by name */ strcpy(ifr.ifr_name, ifname); r = IOCTL(*psock, SIOCGIFINDEX, &ifr); ifindex = ifr.ifr_ifindex; strcpy(ifr.ifr_name, ifname); ifr.ifr_flags = 0; /* reset flags of NIC interface */ r = IOCTL(*psock, SIOCGIFFLAGS, &ifr); /* set flags of NIC interface, here promiscuous and broadcast */ ifr.ifr_flags = ifr.ifr_flags || IFF_PROMISC || IFF_BROADCAST; r = IOCTL(*psock, SIOCGIFFLAGS, &ifr); /* bind socket to protocol, in this case RAW EtherCAT */ sll.sll_family = AF_PACKET; sll.sll_ifindex = ifindex; sll.sll_protocol = htons(ETH_P_ECAT); r = BIND(*psock, (struct sockaddr *)&sll, sizeof(sll)); /* setup ethernet headers in tx buffers so we don't have to repeat it */ for (i = 0; i < EC_MAXBUF; i++) { ec_setupheader(&(port->txbuf[i])); port->rxbufstat[i] = EC_BUF_EMPTY; } ec_setupheader(&(port->txbuf2)); if (r == 0) rval = 1; return rval; }
bool CPassiveSocket::BindMulticast(const char *pInterface, const char *pGroup, uint16 nPort) { bool bRetVal = false; #ifdef WIN32 ULONG inAddr; #else in_addr_t inAddr; #endif //-------------------------------------------------------------------------- // Set the following socket option SO_REUSEADDR. This will allow the file // descriptor to be reused immediately after the socket is closed instead // of setting in a TIMED_WAIT state. //-------------------------------------------------------------------------- memset(&m_stMulticastGroup,0,sizeof(m_stMulticastGroup)); m_stMulticastGroup.sin_family = AF_INET; m_stMulticastGroup.sin_port = htons(nPort); //-------------------------------------------------------------------------- // If no IP Address (interface ethn) is supplied, or the loop back is // specified then bind to any interface, else bind to specified interface. //-------------------------------------------------------------------------- if ((pInterface == NULL) || (!strlen(pInterface))) { m_stMulticastGroup.sin_addr.s_addr = htonl(INADDR_ANY); } else { if ((inAddr = inet_addr(pInterface)) != INADDR_NONE) { m_stMulticastGroup.sin_addr.s_addr = inAddr; } } //-------------------------------------------------------------------------- // Bind to the specified port //-------------------------------------------------------------------------- if (bind(m_socket, (struct sockaddr *)&m_stMulticastGroup, sizeof(m_stMulticastGroup)) == 0) { //---------------------------------------------------------------------- // Join the multicast group //---------------------------------------------------------------------- m_stMulticastRequest.imr_multiaddr.s_addr = inet_addr(pGroup); m_stMulticastRequest.imr_interface.s_addr = m_stMulticastGroup.sin_addr.s_addr; if (SETSOCKOPT(m_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&m_stMulticastRequest, sizeof(m_stMulticastRequest)) == CSimpleSocket::SocketSuccess) { bRetVal = true; } m_timer.SetEndTime(); } m_timer.Initialize(); m_timer.SetStartTime(); //-------------------------------------------------------------------------- // If there was a socket error then close the socket to clean out the // connection in the backlog. //-------------------------------------------------------------------------- TranslateSocketError(); if (bRetVal == false) { Close(); } return bRetVal; }
int main(int argc, char *argv[]) { int c, quit; TstVoipCfg stVoipCfg; TstVoipValue stVoipValue; TstVoipMgrSession stVoipMgrSession; TstVoipPayLoadTypeConfig stVoipPayLoadTypeConfig; TstVoipSlicRing stVoipSlicRing; TstVoipPlayToneConfig cfg; #if 0 stVoipSlicRing.ch_id = 0; stVoipSlicRing.ring_set = 1; SETSOCKOPT(VOIP_MGR_SLIC_RING, &stVoipSlicRing, TstVoipSlicRing, 1); sleep(1); stVoipSlicRing.ch_id = 0; stVoipSlicRing.ring_set = 0; SETSOCKOPT(VOIP_MGR_SLIC_RING, &stVoipSlicRing, TstVoipSlicRing, 1); #endif // start session stVoipCfg.ch_id = 0; stVoipCfg.enable = 1; SETSOCKOPT(VOIP_MGR_PCM_CFG, &stVoipCfg, TstVoipCfg, 1); stVoipCfg.ch_id = 0; stVoipCfg.m_id = 0; stVoipCfg.enable = 1; SETSOCKOPT(VOIP_MGR_CTRL_RTPSESSION, &stVoipCfg, TstVoipCfg, 1); #if 0 stVoipValue.ch_id = 0; stVoipValue.m_id = 0; stVoipValue.value = 7; SETSOCKOPT(VOIP_MGR_SET_SLIC_TX_GAIN, &stVoipValue, TstVoipValue, 1); stVoipValue.value = 7; SETSOCKOPT(VOIP_MGR_SET_SLIC_RX_GAIN, &stVoipValue, TstVoipValue, 1); stVoipCfg.ch_id = 0; stVoipCfg.m_id = 0; stVoipCfg.enable = 1; SETSOCKOPT(VOIP_MGR_DTMF_CFG, &stVoipCfg, TstVoipCfg, 1); SETSOCKOPT(VOIP_MGR_CTRL_TRANSESSION_ID, &stVoipCfg, TstVoipCfg, 1); #endif #if 0 stVoipMgrSession.ch_id = 0; stVoipMgrSession.m_id = 0; stVoipMgrSession.ip_src_addr = htonl(inet_addr("172.21.69.43")); stVoipMgrSession.ip_dst_addr = htonl(inet_addr("172.21.69.91")); stVoipMgrSession.udp_src_port = htons(0x3333); stVoipMgrSession.udp_dst_port = htons(0x3333); stVoipMgrSession.protocol = 0x11; // udp SETSOCKOPT(VOIP_MGR_SET_SESSION, &stVoipMgrSession, TstVoipMgrSession, 1); stVoipPayLoadTypeConfig.ch_id = 0; stVoipPayLoadTypeConfig.m_id = 0; stVoipPayLoadTypeConfig.uPktFormat = rtpPayloadPCMA; stVoipPayLoadTypeConfig.nG723Type = 0; stVoipPayLoadTypeConfig.nFramePerPacket = 1; stVoipPayLoadTypeConfig.bVAD = 0; stVoipPayLoadTypeConfig.bPLC = 1; SETSOCKOPT(VOIP_MGR_SETRTPPAYLOADTYPE, &stVoipPayLoadTypeConfig, TstVoipPayLoadTypeConfig, 1); stVoipCfg.ch_id = 0; stVoipCfg.m_id = 0; stVoipCfg.enable = 1; SETSOCKOPT(VOIP_MGR_RTP_CFG, &stVoipCfg, TstVoipCfg, 1); #endif cfg.ch_id = 0; cfg.m_id = 0; cfg.nTone = 12; cfg.bFlag = 1; cfg.path = 0; SETSOCKOPT(VOIP_MGR_SETPLAYTONE, &cfg, TstVoipPlayToneConfig, 1); return 0; }
static socket_udp *udp_init4(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl) { int reuse = 1, udpbufsize=1048576; struct sockaddr_in s_in; struct in_addr iface_addr; #ifdef WIN32 int recv_buf_size = 65536; #endif socket_udp *s = (socket_udp *)malloc(sizeof(socket_udp)); s->mode = IPv4; s->addr = NULL; s->rx_port = rx_port; s->tx_port = tx_port; s->ttl = ttl; if (inet_ptonxp(AF_INET, addr, &s->addr4) != 1) { struct hostent *h = gethostbyname(addr); if (h == NULL) { socket_error("Can't resolve IP address for %s", addr); free(s); return NULL; } memcpy(&(s->addr4), h->h_addr_list[0], sizeof(s->addr4)); } if (iface != NULL) { if (inet_ptonxp(AF_INET, iface, &iface_addr) != 1) { debug_msg("Illegal interface specification\n"); free(s); return NULL; } } else { iface_addr.s_addr = 0; } s->fd = socket(AF_INET, SOCK_DGRAM, 0); if (s->fd < 0) { socket_error("socket"); if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_SNDBUF, (char *) &udpbufsize, sizeof(udpbufsize)) != 0) { socket_error("setsockopt SO_SNDBUF"); return NULL; } if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_RCVBUF, (char *) &udpbufsize, sizeof(udpbufsize)) != 0) { socket_error("setsockopt SO_RCVBUF"); return NULL; } return NULL; } if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) != 0) { socket_error("setsockopt SO_REUSEADDR"); return NULL; } #ifdef SO_REUSEPORT if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEPORT, (char *) &reuse, sizeof(reuse)) != 0) { socket_error("setsockopt SO_REUSEPORT"); return NULL; } #endif s_in.sin_family = AF_INET; s_in.sin_addr.s_addr = INADDR_ANY; s_in.sin_port = htons(rx_port); if (bind(s->fd, (struct sockaddr *) &s_in, sizeof(s_in)) != 0) { socket_error("bind"); return NULL; } if (IN_MULTICAST(ntohl(s->addr4.s_addr))) { char loop = 1; struct ip_mreq imr; imr.imr_multiaddr.s_addr = s->addr4.s_addr; imr.imr_interface.s_addr = iface_addr.s_addr; if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &imr, sizeof(struct ip_mreq)) != 0) { socket_error("setsockopt IP_ADD_MEMBERSHIP"); return NULL; } #ifndef WIN32 if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) != 0) { socket_error("setsockopt IP_MULTICAST_LOOP"); return NULL; } #endif if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &s->ttl, sizeof(s->ttl)) != 0) { socket_error("setsockopt IP_MULTICAST_TTL"); return NULL; } if (iface_addr.s_addr != 0) { if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_IF, (char *) &iface_addr, sizeof(iface_addr)) != 0) { socket_error("setsockopt IP_MULTICAST_IF"); return NULL; } } } s->addr = strdup(addr); return s; }