/* *=========================================================================== * ipcom_egd *=========================================================================== * Description: This process gathers random data by calling ipcom_random_bingo_lotto() * * Applications can access the random data before the full entropy * has been gathered. This will of course mean that the quality of * the random data will not be as good, but in some situations that * may be a better trade-off than no random data at all. * Parameters: * Returns: * */ IP_STATIC IPCOM_PROCESS(ipcom_egd) { Ipcom_egd_hash_ctx md5_ctx; Ipcom_egd_hash_ctx tmp_md5_ctx; Ip_s32 rnd; Ipcom_tmo tmo; #ifdef IPCOM_EGD_DEBUG int i; #endif ipcom_proc_init(); IPCOM_LOG0(DEBUG, "ipcom_egd :: starting"); ipcom_egd_hash_init(&md5_ctx); ipcom_egd_laps = 0; #ifdef IPCOM_EGD_DEBUG ipcom_memset(ipcom_egd_raw_data, 0, sizeof(ipcom_egd_raw_data)); #endif while(ipcom_egd_laps < IPCOM_RANDOM_LAPS) { ipcom_egd_tmo_flag = 0; if(ipcom_tmo_request(&tmo, ipcom_random_tmo_handler, (int*)&ipcom_egd_tmo_flag, 50) != IPCOM_SUCCESS) { IPCOM_LOG0(ERR, "ipcom_egd :: timeout request failed, seed aborted"); goto exit; } rnd = ipcom_random_bingo_lotto(); #ifdef IPCOM_EGD_DEBUG ipcom_egd_raw_data[ipcom_egd_laps] = rnd; #endif ipcom_egd_hash_update(&md5_ctx, (void*) &rnd, sizeof(Ip_u32)); ipcom_memcpy(&tmp_md5_ctx, &md5_ctx, sizeof(Ipcom_egd_hash_ctx)); ipcom_egd_hash_final(ipcom_random_state, &tmp_md5_ctx); ipcom_egd_laps++; ipcom_millisleep(IPCOM_EGD_SLEEP_TIME); } exit: #ifdef IPCOM_EGD_DEBUG for (i=0; i < ipcom_egd_laps; i++) { IPCOM_LOG2(INFO, "ipcom_egd_raw_data[%d] = %d", i, ipcom_egd_raw_data[i]); ipcom_millisleep(100); } #endif IPCOM_LOG0(DEBUG, "ipcom_egd :: terminating"); ipcom_proc_exit(); }
/* *=========================================================================== * ipppp_work *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC IPCOM_PROCESS(ipppp_work) { ipcom_proc_init(); for (;;) { struct Ipppp_action_work *work; ipcom_sem_wait(ipppp_work_sem); ipcom_mutex_lock(ipppp_work_lock); work = IPCOM_LIST_FIRST(&ipppp_work_queue); ipcom_list_remove(&work->list); ipcom_mutex_unlock(ipppp_work_lock); ipppp_example_action_work(work); ipcom_free(work); } /* ipcom_proc_exit(); */ }
IP_STATIC IPCOM_PROCESS( ipcom_cmd_smptest_client_spawn ) { union { struct Ip_sockaddr sa; #ifdef IPCOM_USE_INET6 struct Ip_sockaddr_in6 sin6; #endif struct Ip_sockaddr_storage ss; struct Ip_sockaddr_in sin; } addr; Ip_fd socket; unsigned char *buf = 0; int portadd = spawn_number_client++; int opt_val = 1; int sec = SECONDS_CLIENT; int send = 0; int num_sends = 0; unsigned long num_bytes = 0; ipcom_proc_init(); ipcom_memset( &addr.ss, 0, sizeof( addr.ss ) ); ipcom_memcpy( &addr.sa, smp_opt_client.res->ai_addr, smp_opt_client.res->ai_addrlen ); socket = ipcom_socket( smp_opt_client.res->ai_family, smp_opt_client.res->ai_socktype, smp_opt_client.res->ai_protocol ); if (socket == IP_SOCKERR) { ipcom_printf("Failed to create socket for thread %d: %s"IP_LF, portadd, ipcom_strerror(ipcom_errno)); return_client = 1; ipcom_sem_post( sem_wait_client ); return; } if ( 0 != ipcom_setsockopt(socket, IP_SOL_SOCKET, IP_SO_REUSEPORT, &opt_val, sizeof (opt_val)) ) { ipcom_printf("ipcom_setsockopt failed: %s"IP_LF, ipcom_strerror(ipcom_errno)); return_client = 1; ipcom_sem_post( sem_wait_client ); return; } if ( 0 != ipcom_socketioctl( socket, IP_X_SIOCSINTR, &sec ) ) { ipcom_printf("ipcom_socketioctl failed: %s"IP_LF, ipcom_strerror(ipcom_errno)); return_client = 1; ipcom_sem_post( sem_wait_client ); return; } addr.sin.sin_port = ip_htons( smp_opt_client.port + portadd ); /* port is in the same place for IPv4 and IPv6 */ if ( smp_opt_client.tcp ) { if ( 0 != ipcom_connect( socket, &addr.sa, smp_opt_client.res->ai_addrlen ) ) { ipcom_printf("Thread %d failed to connect: %s"IP_LF, portadd, ipcom_strerror(ipcom_errno)); return_client = 1; ipcom_sem_post( sem_wait_client ); return; } if ( verbose ) ipcom_printf("Thread %d connected to port %d"IP_LF, portadd, smp_opt_client.port + portadd ); } buf = ipcom_malloc( smp_opt_client.num_bytes ); while ( 1 ) { if ( smp_opt_client.tcp ) send = ipcom_send( socket, buf, smp_opt_client.num_bytes, 0); else send = ipcom_sendto( socket, buf, smp_opt_client.num_bytes, 0, &addr.sa, smp_opt_client.res->ai_addrlen ); if ( send > 0 ) num_bytes += send; num_sends++; if ( send == 0 ) { ipcom_printf( "Error: Disconnected"IP_LF ); return_client = 1; break; } else if ( send < 0 ) { if ( ipcom_errno == IP_ERRNO_EINTR ) { if ( verbose ) { ipcom_printf("Thread %d done."IP_LF, portadd ); ipcom_printf(" Sends: %d"IP_LF, num_sends ); ipcom_printf(" MB/s: %f"IP_LF, ((float)(num_bytes)/(1024.0f*1024.0f) )/5.0f ); } break; } return_client = 1; ipcom_printf("Error on thread %d: %s"IP_LF, portadd, ipcom_strerror(ipcom_errno)); break; } } if ( verbose ) { if ( spawn_number_client != smp_opt_client.num_sock ) { ipcom_printf("Error. Only %d client-sockets seemed to work."IP_LF, spawn_number_client ); } } ipcom_socketclose( socket ); ipcom_free( buf ); if ( 0 == ipcom_atomic_sub_and_return( &num_wait_client, 1 ) ) ipcom_sem_post( sem_wait_client ); ipcom_proc_exit(); }
IP_STATIC IPCOM_PROCESS( ipcom_cmd_smptest_server_spawn ) { union { struct Ip_sockaddr sa; #ifdef IPCOM_USE_INET6 struct Ip_sockaddr_in6 sin6; #endif struct Ip_sockaddr_storage ss; struct Ip_sockaddr_in sin; } addr; Ip_fd listen_socket; Ip_fd connect_sock = 0; int opt_val = 1; int portadd = spawn_number_server++; int bytes = 0; int sec = SECONDS_CLIENT + SECONDS_SERVER; unsigned char *buf = 0; int num_recives = 0; unsigned long num_bytes = 0; struct Ip_sockaddr from; struct Ip_linger linger; Ip_socklen_t from_length = 0; int retry_count = 0; ipcom_proc_init(); ipcom_memset( &addr.ss, 0, sizeof( addr.ss ) ); ipcom_memcpy( &addr.sa, smp_opt_server.res->ai_addr, smp_opt_server.res->ai_addrlen ); linger.l_onoff = 1; linger.l_linger = 2; listen_socket = ipcom_socket( smp_opt_server.res->ai_family, smp_opt_server.res->ai_socktype, smp_opt_server.res->ai_protocol ); if (listen_socket == IP_SOCKERR) { ipcom_printf("Failed to create socket: %s"IP_LF, ipcom_strerror(ipcom_errno)); return_server = 1; ipcom_sem_post( sem_wait_server ); return; } if ( 0 != ipcom_setsockopt(listen_socket, IP_SOL_SOCKET, IP_SO_REUSEPORT, &opt_val, sizeof (opt_val)) ) { ipcom_printf("ipcom_setsockopt failed: %s"IP_LF, ipcom_strerror(ipcom_errno)); return_server = 1; ipcom_sem_post( sem_wait_server ); return; } addr.sin.sin_port = ip_htons( smp_opt_server.port + portadd ); /* port is in the same place for IPv4 and IPv6 */ if ( 0 != ipcom_bind( listen_socket, &addr.sa, sizeof( addr.ss ) ) ) { ipcom_printf("Failed to bind: %s"IP_LF, ipcom_strerror(ipcom_errno)); return_server = 1; ipcom_sem_post( sem_wait_server ); return; } buf = ipcom_malloc( smp_opt_server.num_bytes ); if ( smp_opt_server.tcp ) { if ( -1 == ipcom_listen( listen_socket, 0 ) ) { ipcom_printf("Listen failed: %s"IP_LF, ipcom_strerror(ipcom_errno)); return_server = 1; ipcom_sem_post( sem_wait_server ); return; } if ( verbose ) ipcom_printf("Thread %d listens to %s:%d"IP_LF, portadd, smp_opt_server.res->ai_canonname, ip_ntohs( addr.sin.sin_port ) ); } if ( 0 == ipcom_atomic_sub_and_return( &listen_wait, 1 ) ) { /* Send to the test-server or write to stdout? */ if ( server_out >= 0 ) { char ready[] = "Ready."; ipcom_socketwrite(server_out, ready, 8 ); } else ipcom_printf("Ready."IP_LF ); } if ( 0 != ipcom_socketioctl( listen_socket, IP_X_SIOCSINTR, &sec ) ) { ipcom_printf("ipcom_socketioctl failed: %s"IP_LF, ipcom_strerror(ipcom_errno)); return_server = 1; ipcom_sem_post( sem_wait_server ); return; } if ( smp_opt_server.tcp ) { retry: connect_sock = ipcom_accept( listen_socket, IP_NULL, 0 ); if ( -1 == connect_sock ) { if ( ipcom_errno == IP_ERRNO_EINTR ) { if ( verbose ) { if ( ++retry_count < 5 ) { ipcom_printf("Accept failed for thread %d: %s.. Retrying."IP_LF, portadd, ipcom_strerror(ipcom_errno)); goto retry; } } } ipcom_printf("Accept failed for thread %d: %s"IP_LF, portadd, ipcom_strerror(ipcom_errno)); return_server = 1; ipcom_socketclose( listen_socket ); ipcom_sem_post( sem_wait_server ); return; } if ( 0 != ipcom_socketioctl( connect_sock, IP_X_SIOCSINTR, &sec ) ) { ipcom_printf("ipcom_socketioctl failed: %s"IP_LF, ipcom_strerror(ipcom_errno)); return_server = 1; ipcom_sem_post( sem_wait_server ); return; } if ( 0 != ipcom_setsockopt( connect_sock, IP_SOL_SOCKET, IP_SO_LINGER, &linger, sizeof (linger)) ) { ipcom_printf("ipcom_setsockopt failed: %s"IP_LF, ipcom_strerror(ipcom_errno)); return_server = 1; ipcom_sem_post( sem_wait_server ); return; } } while ( 1 ) { num_recives++; if ( smp_opt_server.tcp ) bytes = ipcom_recv( connect_sock, buf, smp_opt_server.num_bytes, 0); else { bytes = ipcom_recvfrom( listen_socket, buf, smp_opt_server.num_bytes, 0, &from, &from_length ); if ( num_recives == 1 && 0 == smp_opt_server.tcp ) { sec = SECONDS_CLIENT+2+portadd; if ( 0 != ipcom_socketioctl( listen_socket, IP_X_SIOCSINTR, &sec ) ) { ipcom_printf("ipcom_socketioctl failed: %s"IP_LF, ipcom_strerror(ipcom_errno)); return_server = 1; ipcom_sem_post( sem_wait_server ); return; } } } if ( bytes > 0 ) num_bytes += bytes; if (bytes == 0) { if ( verbose ) { ipcom_printf("Thread %d done."IP_LF, portadd ); ipcom_printf(" Recives: %d"IP_LF, num_recives ); ipcom_printf(" MB/s: %f"IP_LF, ((float)(num_bytes)/(1024.0f*1024.0f) )/5.0f ); } break; } else if (bytes < 0) { if ( ipcom_errno == IP_ERRNO_EINTR ) { if ( smp_opt_server.tcp ) { return_server = 1; ipcom_printf("Error! Out of time!"IP_LF ); break; } else { if ( verbose ) { ipcom_printf("Thread %d done."IP_LF, portadd ); ipcom_printf(" Recives: %d"IP_LF, num_recives ); ipcom_printf(" MB/s: %f"IP_LF, ((float)(num_bytes)/(1024.0f*1024.0f) )/5.0f ); } break; } } else if ( bytes == IP_SOCKERR ) /* Connection reset by peer */ { } return_server = 1; ipcom_printf("recv failed: %s"IP_LF, ipcom_strerror(ipcom_errno)); return; } } if ( verbose ) { if ( spawn_number_server != smp_opt_server.num_sock ) { ipcom_printf("Error. Only %d server-sockets seemed to work."IP_LF, spawn_number_server ); } } if ( smp_opt_server.tcp ) ipcom_shutdown( connect_sock, IP_SHUT_RDWR ); ipcom_free( buf ); ipcom_socketclose( listen_socket ); if ( 0 == ipcom_atomic_sub_and_return( &num_wait_server, 1 ) ) ipcom_sem_post( sem_wait_server ); if ( smp_opt_server.tcp ) ipcom_socketclose( connect_sock ); ipcom_proc_exit(); }
/* *=========================================================================== * ipl2tps *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC IPCOM_PROCESS(ipl2tps) { Ip_fd ipd_fd = IP_INVALID_SOCKET; Ip_bool ipd_init = 0; #ifdef IPPPP_USE_PPPL2TP Ip_fd ipl2tp_ppp_ipc_recv_fd = IP_INVALID_SOCKET; #endif ipcom_proc_init(); #ifdef IPPPP_USE_PPPL2TP if ((ipl2tp_ppp_ipc_recv_fd = ipppp_pppl2tp_pkt_que_open()) == IP_INVALID_SOCKET) { ipcom_printf("Cannot allocate data packet output socket, errno: %d"IP_LF, ipcom_errno); goto leave; } #endif /* Get socket */ if ((udp_fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, IP_IPPROTO_UDP)) < 0) { ipcom_printf("Cannot allocate socket, errno: %d"IP_LF, ipcom_errno); goto leave; } else { union Ip_sockaddr_union uaddr; /* Bind to L2TP port */ ipcom_memset(&uaddr, 0, sizeof(uaddr)); uaddr.sin.sin_family = IP_AF_INET; uaddr.sin.sin_addr.s_addr = IP_INADDR_ANY; uaddr.sin.sin_port = ip_htons(IPL2TP_PORT_NUMBER); uaddr.sin.sin_len = sizeof(struct Ip_sockaddr_in); if (ipcom_bind(udp_fd, &uaddr.sa, sizeof(struct Ip_sockaddr_in)) < 0) { ipcom_printf("Cannot bind socket, errno: %d"IP_LF, ipcom_errno); ipcom_socketclose(udp_fd); goto leave; } } /* Get socket */ if ((ip_fd = ipcom_socket(IP_AF_INET, IP_SOCK_RAW, IP_IPPROTO_L2TP)) < 0) { ipcom_printf("Cannot allocate socket, errno: %d"IP_LF, ipcom_errno); ipcom_socketclose(udp_fd); goto leave; } /* Init IPD */ if (ipd_init == 0 && ipcom_ipd_init("ipl2tp", IPCOM_SUCCESS, &ipd_fd) != IPCOM_SUCCESS) { ipcom_printf("Cannot initialize ipd: %s"IP_LF, ipcom_strerror(ipcom_errno)); goto leave; } ipd_init = 1; /* Enter read loop (never return) */ for (;;) { Ip_fd_set fds; Ipl2tp_example_fd_entry_t *fd; int fd_max; struct Ip_timeval tv; int ret; IP_FD_ZERO(&fds); IP_FD_SET(udp_fd, &fds); IP_FD_SET(ip_fd, &fds); IP_FD_SET(ipd_fd, &fds); fd_max = IP_MAX(udp_fd, ip_fd); fd_max = IP_MAX(fd_max, ipd_fd); #ifdef IPPPP_USE_PPPL2TP IP_FD_SET(ipl2tp_ppp_ipc_recv_fd, &fds); fd_max = IP_MAX(fd_max, ipl2tp_ppp_ipc_recv_fd); #endif fd = IPCOM_LIST_FIRST(&ipl2tp_example_fds); while (fd != IP_NULL) { Ipl2tp_example_fd_entry_t *nfd = IPCOM_LIST_NEXT(&fd->next); if (fd->data != IP_NULL) { IP_FD_SET(fd->fd, &fds); fd_max = IP_MAX(fd_max, fd->fd); } else { ipcom_list_remove(&fd->next); ipcom_socketclose(fd->fd); ipcom_free(fd); } fd = nfd; } tv.tv_sec = 0; tv.tv_usec = 10000; if ((ret = ipcom_socketselect(fd_max + 1, &fds, IP_NULL, IP_NULL, &tv)) > 0) { union Ip_sockaddr_union uaddr; int length; Ip_u8 *buffer; if (IP_FD_ISSET(ipd_fd, &fds)) { int event; event = ipcom_ipd_input(ipd_fd); if (event == IPCOM_IPD_EVENT_RECONFIGURE) goto leave; } #ifdef IPPPP_USE_PPPL2TP if (IP_FD_ISSET(ipl2tp_ppp_ipc_recv_fd, &fds)) { Ipppp_pppl2tp_pkt_que_entry que_entry; Ipcom_netif *netif; Ipcom_pkt *pkt; char addrstr[IP_INET_ADDRSTRLEN]; /* Read message and feed it to L2TP main input */ if (ipppp_pppl2tp_pkt_que_recv(&que_entry, &uaddr) == IPCOM_SUCCESS) { if ((que_entry.netif == IP_NULL) || (que_entry.pkt == IP_NULL)) { ipcom_printf("ipl2tps: L2TPv2 pkt from %s:%d contains null ptr(s)."IP_LF, ipcom_inet_ntop(IP_AF_INET, &uaddr.sin.sin_addr, addrstr, sizeof(addrstr)), ipcom_ntohs(uaddr.sin.sin_port)); } else { pkt = que_entry.pkt; netif = que_entry.netif; ipppp_pppl2tp_output(netif, pkt); } } else ipcom_printf("ipl2tps: PPP pkt recv failed."IP_LF); } #endif /* IPPPP_USE_PPPL2TP */ if (IP_FD_ISSET(udp_fd, &fds)) { /* Read message and feed it to L2TP main input */ if ((length = ipl2tp_l2tp_read(udp_fd, &buffer, &uaddr)) > 0) { ipl2tp_api_l2tp_input(buffer, buffer + HEADER_SPACE, (Ip_u16)length, &uaddr, IPL2TP_ATTR_TRANSPORT_UDP); /* Free buffer if not in PPP output queue */ if (ipl2tp_buffer_free) { ipl2tp_cache_free(buffer); } } } if (IP_FD_ISSET(ip_fd, &fds)) { /* Read message and feed it to L2TP main input */ if ((length = ipl2tp_l2tp_read(ip_fd, &buffer, &uaddr)) > 0) { /* Remove the IP header before invoking */ ipl2tp_api_l2tp_input(buffer, buffer + HEADER_SPACE + 20, (Ip_u16)(length - 20), &uaddr, IPL2TP_ATTR_TRANSPORT_IP); /* Free buffer if not in PPP output queue */ if (ipl2tp_buffer_free) { ipl2tp_cache_free(buffer); } } } fd = IPCOM_LIST_FIRST(&ipl2tp_example_fds); while (fd != IP_NULL) { Ipl2tp_example_fd_entry_t *nfd = IPCOM_LIST_NEXT(&fd->next); if (fd->data!= IP_NULL && IP_FD_ISSET(fd->fd, &fds)) { /* Read message and feed it to L2TP main input */ if ((length = ipl2tp_l2tp_read(fd->fd, &buffer, &uaddr)) > 0) { if (fd->data != IP_NULL) { (*fd->data) (fd, buffer, buffer + HEADER_SPACE, length); } /* Free buffer if not in PPP output queue */ if (ipl2tp_buffer_free) { ipl2tp_cache_free(buffer); } } } fd = nfd; } } else if (ret < 0) { ipcom_printf("select error"IP_LF); } } leave: /* Have to call ipd init if not done yet */ if (ipd_init == 0 && ipcom_ipd_init("ipl2tp", IPCOM_ERR_FAILED, &ipd_fd) == IPCOM_SUCCESS) { ipd_init = 1; } if (ipd_init != 0) { (void)ipcom_ipd_exit("ipl2tp", ipd_fd); } ipcom_proc_exit(); }