int ipaugenblick_v4_connect_bind_socket(int sock,unsigned int ipaddr,unsigned short port,int is_connect) { ipaugenblick_cmd_t *cmd; cmd = ipaugenblick_get_free_command_buf(); if(!cmd) { ipaugenblick_stats_cannot_allocate_cmd++; return -1; } cmd->cmd = IPAUGENBLICK_SOCKET_CONNECT_BIND_COMMAND; cmd->ringset_idx = sock; cmd->parent_idx = local_socket_descriptors[sock].select; cmd->u.socket_connect_bind.ipaddr = ipaddr; cmd->u.socket_connect_bind.port = port; cmd->u.socket_connect_bind.is_connect = is_connect; if(ipaugenblick_enqueue_command_buf(cmd)) { ipaugenblick_free_command_buf(cmd); return -2; } if(is_connect) { local_socket_descriptors[sock].remote_ipaddr = ipaddr; local_socket_descriptors[sock].remote_port = port; } else { local_socket_descriptors[sock].local_ipaddr = ipaddr; local_socket_descriptors[sock].local_port = port; } return 0; }
void sig_handler(int signum) { uint32_t i; ipaugenblick_cmd_t *cmd; //printf("%s %d %d\n",__FILE__,__LINE__,signum); if(signum == SIGUSR1) { /* T.B.D. do something to wake up the thread */ return; } syslog(LOG_INFO,"terminating on signal %d\n",signum); for(i = 0;i < IPAUGENBLICK_CONNECTION_POOL_SIZE;i++) { if(local_socket_descriptors[i].socket) { ipaugenblick_close(local_socket_descriptors[i].socket->connection_idx); } } cmd = ipaugenblick_get_free_command_buf(); if(cmd) { cmd->cmd = IPAUGENBLICK_DISCONNECT_CLIENT; cmd->ringset_idx = g_client_ringset_idx; if(ipaugenblick_enqueue_command_buf(cmd)) { ipaugenblick_free_command_buf(cmd); } } signal(signum,SIG_DFL); g_print_stats_loop = 0; kill(getpid(),signum); }
int ipaugenblick_open_socket(int family,int type,int parent) { ipaugenblick_socket_t *ipaugenblick_socket; ipaugenblick_cmd_t *cmd; if(rte_ring_dequeue(free_connections_ring,(void **)&ipaugenblick_socket)) { syslog(LOG_ERR,"%s %d\n",__FILE__,__LINE__); return -1; } /* allocate a ringset (cmd/tx/rx) here */ cmd = ipaugenblick_get_free_command_buf(); if(!cmd) { ipaugenblick_stats_cannot_allocate_cmd++; return -2; } cmd->cmd = IPAUGENBLICK_OPEN_SOCKET_COMMAND; cmd->ringset_idx = ipaugenblick_socket->connection_idx; cmd->parent_idx = parent; cmd->u.open_sock.family = family; cmd->u.open_sock.type = type; cmd->u.open_sock.pid = getpid(); if(ipaugenblick_enqueue_command_buf(cmd)) { ipaugenblick_free_command_buf(cmd); return -3; } local_socket_descriptors[ipaugenblick_socket->connection_idx].socket = ipaugenblick_socket; if(parent != -1) local_socket_descriptors[ipaugenblick_socket->connection_idx].select = parent; return ipaugenblick_socket->connection_idx; }
int ipaugenblick_create_client(ipaugenblick_update_cbk_t update_cbk) { int ringset_idx; ipaugenblick_cmd_t *cmd; char ringname[1024]; if(rte_ring_dequeue(free_clients_ring,(void **)&ringset_idx)) { syslog(LOG_ERR,"%s %d\n",__FILE__,__LINE__); return -1; } sprintf(ringname,"%s%d",FREE_CLIENTS_RING,ringset_idx); client_ring = rte_ring_lookup(ringname); if(!client_ring) { syslog(LOG_ERR,"%s %d\n",__FILE__,__LINE__); return -2; } cmd = ipaugenblick_get_free_command_buf(); if(!cmd) { ipaugenblick_stats_cannot_allocate_cmd++; return -3; } cmd->cmd = IPAUGENBLICK_CONNECT_CLIENT; cmd->ringset_idx = ringset_idx; if(ipaugenblick_enqueue_command_buf(cmd)) { ipaugenblick_free_command_buf(cmd); return -3; } g_client_ringset_idx = (uint32_t)ringset_idx; ipaugenblick_update_cbk = update_cbk; return 0; }
static inline void ipaugenblick_notify_empty_tx_buffers(int sock) { ipaugenblick_cmd_t *cmd; cmd = ipaugenblick_get_free_command_buf(); if(!cmd) { ipaugenblick_stats_cannot_allocate_cmd++; return; } cmd->cmd = IPAUGENBLICK_SOCKET_TX_POOL_EMPTY_COMMAND; cmd->ringset_idx = sock; if(ipaugenblick_enqueue_command_buf(cmd)) { ipaugenblick_free_command_buf(cmd); } }
/* close any socket */ void ipaugenblick_close(int sock) { ipaugenblick_cmd_t *cmd; cmd = ipaugenblick_get_free_command_buf(); if(!cmd) { ipaugenblick_stats_cannot_allocate_cmd++; return; } cmd->cmd = IPAUGENBLICK_SOCKET_CLOSE_COMMAND; cmd->ringset_idx = sock; cmd->parent_idx = local_socket_descriptors[sock].select; if(ipaugenblick_enqueue_command_buf(cmd)) { ipaugenblick_free_command_buf(cmd); } }
int ipaugenblick_listen_socket(int sock) { ipaugenblick_cmd_t *cmd; cmd = ipaugenblick_get_free_command_buf(); if(!cmd) { ipaugenblick_stats_cannot_allocate_cmd++; return -1; } cmd->cmd = IPAUGENBLICK_LISTEN_SOCKET_COMMAND; cmd->ringset_idx = sock; cmd->parent_idx = local_socket_descriptors[sock].select; if(ipaugenblick_enqueue_command_buf(cmd)) { ipaugenblick_free_command_buf(cmd); return -2; } return 0; }
int ipaugenblick_set_socket_select(int sock,int select) { ipaugenblick_cmd_t *cmd; if(sock < 0) return -1; cmd = ipaugenblick_get_free_command_buf(); if(!cmd) { ipaugenblick_stats_cannot_allocate_cmd++; return -2; } cmd->cmd = IPAUGENBLICK_SET_SOCKET_SELECT_COMMAND; cmd->ringset_idx = sock; cmd->u.set_socket_select.socket_select = select; cmd->u.set_socket_select.pid = getpid(); if(ipaugenblick_enqueue_command_buf(cmd)) { ipaugenblick_free_command_buf(cmd); return -3; } local_socket_descriptors[sock].select = select; }
static inline void process_commands() { int ringset_idx; ipaugenblick_cmd_t *cmd; struct rte_mbuf *mbuf; struct socket *sock; char *p; struct sockaddr_in addr; struct sockaddr_in *p_sockaddr; struct rtentry rtentry; int len; cmd = ipaugenblick_dequeue_command_buf(); if(!cmd) return; switch(cmd->cmd) { case IPAUGENBLICK_OPEN_SOCKET_COMMAND: ipaugenblick_log(IPAUGENBLICK_LOG_DEBUG,"open_sock %x %x %x %x\n",cmd->u.open_sock.family,cmd->u.open_sock.type); sock = app_glue_create_socket(cmd->u.open_sock.family,cmd->u.open_sock.type); if(sock) { ipaugenblick_log(IPAUGENBLICK_LOG_DEBUG,"setting user data %p\n",sock); socket_satelite_data[cmd->ringset_idx].ringset_idx = cmd->ringset_idx; socket_satelite_data[cmd->ringset_idx].parent_idx = cmd->parent_idx; socket_satelite_data[cmd->ringset_idx].apppid = cmd->u.open_sock.pid; app_glue_set_user_data(sock,(void *)&socket_satelite_data[cmd->ringset_idx]); socket_satelite_data[cmd->ringset_idx].socket = sock; ipaugenblick_log(IPAUGENBLICK_LOG_DEBUG,"%d setting tx_space %d\n",__LINE__,sk_stream_wspace(sock->sk)); user_set_socket_tx_space(&g_ipaugenblick_sockets[socket_satelite_data[cmd->ringset_idx].ringset_idx].tx_space,sk_stream_wspace(sock->sk)); } ipaugenblick_log(IPAUGENBLICK_LOG_DEBUG,"Done\n"); break; case IPAUGENBLICK_SOCKET_CONNECT_BIND_COMMAND: if(socket_satelite_data[cmd->ringset_idx].socket) { if(cmd->u.socket_connect_bind.is_connect) { ipaugenblick_log(IPAUGENBLICK_LOG_DEBUG,"connect %x\n",cmd->ringset_idx); if(app_glue_v4_connect(socket_satelite_data[cmd->ringset_idx].socket, cmd->u.socket_connect_bind.ipaddr, cmd->u.socket_connect_bind.port)) { ipaugenblick_log(IPAUGENBLICK_LOG_ERR,"failed to connect socket\n"); } else { ipaugenblick_log(IPAUGENBLICK_LOG_DEBUG,"socket connected\n"); len = sizeof(addr); inet_getname(socket_satelite_data[cmd->ringset_idx].socket,&addr,&len,0); g_ipaugenblick_sockets[cmd->ringset_idx].local_ipaddr = addr.sin_addr.s_addr; g_ipaugenblick_sockets[cmd->ringset_idx].local_port = addr.sin_port; } } else { ipaugenblick_log(IPAUGENBLICK_LOG_DEBUG,"bind %x\n",cmd->ringset_idx); if(app_glue_v4_bind(socket_satelite_data[cmd->ringset_idx].socket, cmd->u.socket_connect_bind.ipaddr, cmd->u.socket_connect_bind.port)) { ipaugenblick_log(IPAUGENBLICK_LOG_ERR,"cannot bind %x %x\n",cmd->u.socket_connect_bind.ipaddr,cmd->u.socket_connect_bind.port); } } } else { ipaugenblick_log(IPAUGENBLICK_LOG_ERR,"no socket to invoke command!!!\n"); } break; case IPAUGENBLICK_LISTEN_SOCKET_COMMAND: ipaugenblick_log(IPAUGENBLICK_LOG_DEBUG,"listen %x\n",cmd->ringset_idx); if(app_glue_v4_listen(socket_satelite_data[cmd->ringset_idx].socket)) { ipaugenblick_log(IPAUGENBLICK_LOG_ERR,"failed listening\n"); } break; case IPAUGENBLICK_SOCKET_CLOSE_COMMAND: if(socket_satelite_data[cmd->ringset_idx].socket) { // ipaugenblick_log(IPAUGENBLICK_LOG_INFO,"closing socket %d %p\n",cmd->ringset_idx,socket_satelite_data[cmd->ringset_idx].socket); // printf("%s %d %p\n",__FILE__,__LINE__,socket_satelite_data[cmd->ringset_idx].socket); // user_on_transmission_opportunity(socket_satelite_data[cmd->ringset_idx].socket); user_flush_rx_tx((struct socket *)socket_satelite_data[cmd->ringset_idx].socket); app_glue_close_socket((struct socket *)socket_satelite_data[cmd->ringset_idx].socket); socket_satelite_data[cmd->ringset_idx].socket = NULL; socket_satelite_data[cmd->ringset_idx].ringset_idx = -1; socket_satelite_data[cmd->ringset_idx].parent_idx = -1; ipaugenblick_free_socket(cmd->ringset_idx); user_sockets_closed++; } break; case IPAUGENBLICK_SOCKET_TX_KICK_COMMAND: if(socket_satelite_data[cmd->ringset_idx].socket) { user_kick_tx++; // user_data_available_cbk(socket_satelite_data[cmd->ringset_idx].socket); user_on_transmission_opportunity(socket_satelite_data[cmd->ringset_idx].socket); } break; case IPAUGENBLICK_SOCKET_RX_KICK_COMMAND: if(socket_satelite_data[cmd->ringset_idx].socket) { user_kick_rx++; user_data_available_cbk(socket_satelite_data[cmd->ringset_idx].socket); // user_on_transmission_opportunity(socket_satelite_data[cmd->ringset_idx].socket); } break; case IPAUGENBLICK_SET_SOCKET_RING_COMMAND: //ipaugenblick_log(IPAUGENBLICK_LOG_DEBUG,"%s %d %d %d %p\n",__FILE__,__LINE__,cmd->ringset_idx,cmd->parent_idx,cmd->u.set_socket_ring.socket_descr); socket_satelite_data[cmd->ringset_idx].ringset_idx = cmd->ringset_idx; if(cmd->parent_idx != -1) socket_satelite_data[cmd->ringset_idx].parent_idx = cmd->parent_idx; socket_satelite_data[cmd->ringset_idx].apppid = cmd->u.set_socket_ring.pid; app_glue_set_user_data(cmd->u.set_socket_ring.socket_descr,&socket_satelite_data[cmd->ringset_idx]); socket_satelite_data[cmd->ringset_idx].socket = cmd->u.set_socket_ring.socket_descr; //ipaugenblick_log(IPAUGENBLICK_LOG_DEBUG,"setting tx space: %d connidx %d\n",sk_stream_wspace(socket_satelite_data[cmd->ringset_idx].socket->sk),g_ipaugenblick_sockets[socket_satelite_data[cmd->ringset_idx].ringset_idx].connection_idx); user_set_socket_tx_space(&g_ipaugenblick_sockets[socket_satelite_data[cmd->ringset_idx].ringset_idx].tx_space,sk_stream_wspace(socket_satelite_data[cmd->ringset_idx].socket->sk)); // user_on_transmission_opportunity(socket_satelite_data[cmd->ringset_idx].socket); user_data_available_cbk(socket_satelite_data[cmd->ringset_idx].socket); ipaugenblick_mark_writable(&socket_satelite_data[cmd->ringset_idx]); ipaugenblick_mark_readable(&socket_satelite_data[cmd->ringset_idx]); user_client_app_accepted++; break; case IPAUGENBLICK_SET_SOCKET_SELECT_COMMAND: // ipaugenblick_log(IPAUGENBLICK_LOG_DEBUG,"setting selector %d for socket %d\n",cmd->u.set_socket_select.socket_select,cmd->ringset_idx); socket_satelite_data[cmd->ringset_idx].parent_idx = cmd->u.set_socket_select.socket_select; socket_satelite_data[cmd->ringset_idx].apppid = cmd->u.set_socket_select.pid; user_data_available_cbk(socket_satelite_data[cmd->ringset_idx].socket); ipaugenblick_mark_writable(&socket_satelite_data[cmd->ringset_idx]); ipaugenblick_mark_readable(&socket_satelite_data[cmd->ringset_idx]); break; case IPAUGENBLICK_SOCKET_TX_POOL_EMPTY_COMMAND: if(socket_satelite_data[cmd->ringset_idx].socket) { if(!socket_satelite_data[cmd->ringset_idx].socket->buffers_available_notification_queue_present) { TAILQ_INSERT_TAIL(&buffers_available_notification_socket_list_head,socket_satelite_data[cmd->ringset_idx].socket,buffers_available_notification_queue_entry); socket_satelite_data[cmd->ringset_idx].socket->buffers_available_notification_queue_present = 1; if(socket_satelite_data[cmd->ringset_idx].socket->type == SOCK_DGRAM) user_set_socket_tx_space(&g_ipaugenblick_sockets[socket_satelite_data[cmd->ringset_idx].ringset_idx].tx_space,sk_stream_wspace(socket_satelite_data[cmd->ringset_idx].socket->sk)); } } break; case IPAUGENBLICK_ROUTE_ADD_COMMAND: memset((void *)&rtentry,0,sizeof(rtentry)); rtentry.rt_metric = cmd->u.route.metric; rtentry.rt_flags = RTF_UP|RTF_GATEWAY; p_sockaddr = (struct sockaddr_in *)&rtentry.rt_dst; p_sockaddr->sin_family = AF_INET; p_sockaddr->sin_addr.s_addr = cmd->u.route.dest_ipaddr; p_sockaddr = (struct sockaddr_in *)&rtentry.rt_gateway; p_sockaddr->sin_family = AF_INET; p_sockaddr->sin_addr.s_addr = cmd->u.route.next_hop; p_sockaddr = (struct sockaddr_in *)&rtentry.rt_genmask; p_sockaddr->sin_family = AF_INET; p_sockaddr->sin_addr.s_addr = cmd->u.route.dest_mask; if(ip_rt_ioctl(&init_net,SIOCADDRT,&rtentry)) { ipaugenblick_log(IPAUGENBLICK_LOG_ERR,"CANNOT ADD ROUTE ENTRY %x %x %x\n", ((struct sockaddr_in *)&rtentry.rt_dst)->sin_addr.s_addr, ((struct sockaddr_in *)&rtentry.rt_gateway)->sin_addr.s_addr, ((struct sockaddr_in *)&rtentry.rt_genmask)->sin_addr.s_addr); } else { ipaugenblick_log(IPAUGENBLICK_LOG_INFO,"ROUTE ENTRY %x %x %x is added\n", ((struct sockaddr_in *)&rtentry.rt_dst)->sin_addr.s_addr, ((struct sockaddr_in *)&rtentry.rt_gateway)->sin_addr.s_addr, ((struct sockaddr_in *)&rtentry.rt_genmask)->sin_addr.s_addr); } break; case IPAUGENBLICK_ROUTE_DEL_COMMAND: memset((void *)&rtentry,0,sizeof(rtentry)); p_sockaddr = (struct sockaddr_in *)&rtentry.rt_dst; p_sockaddr->sin_family = AF_INET; p_sockaddr->sin_addr.s_addr = cmd->u.route.dest_ipaddr; p_sockaddr = (struct sockaddr_in *)&rtentry.rt_gateway; p_sockaddr->sin_family = AF_INET; p_sockaddr->sin_addr.s_addr = cmd->u.route.next_hop; p_sockaddr = (struct sockaddr_in *)&rtentry.rt_genmask; p_sockaddr->sin_family = AF_INET; p_sockaddr->sin_addr.s_addr = cmd->u.route.dest_mask; if(ip_rt_ioctl(&init_net,SIOCDELRT,&rtentry)) { ipaugenblick_log(IPAUGENBLICK_LOG_ERR,"CANNOT DELETE ROUTE ENTRY %x %x %x\n", ((struct sockaddr_in *)&rtentry.rt_dst)->sin_addr.s_addr, ((struct sockaddr_in *)&rtentry.rt_gateway)->sin_addr.s_addr, ((struct sockaddr_in *)&rtentry.rt_genmask)->sin_addr.s_addr); } else { ipaugenblick_log(IPAUGENBLICK_LOG_INFO,"ROUTE ENTRY %x %x %x is deleted\n", ((struct sockaddr_in *)&rtentry.rt_dst)->sin_addr.s_addr, ((struct sockaddr_in *)&rtentry.rt_gateway)->sin_addr.s_addr, ((struct sockaddr_in *)&rtentry.rt_genmask)->sin_addr.s_addr); } break; case IPAUGENBLICK_CONNECT_CLIENT: if(cmd->ringset_idx >= IPAUGENBLICK_CLIENTS_POOL_SIZE) { break; } if(!ipaugenblick_clients[cmd->ringset_idx].is_busy) { TAILQ_INSERT_TAIL(&ipaugenblick_clients_list_head,&ipaugenblick_clients[cmd->ringset_idx],queue_entry); ipaugenblick_clients[cmd->ringset_idx].is_busy = 1; on_client_connect(cmd->ringset_idx); } break; case IPAUGENBLICK_DISCONNECT_CLIENT: if(cmd->ringset_idx >= IPAUGENBLICK_CLIENTS_POOL_SIZE) { break; } if(ipaugenblick_clients[cmd->ringset_idx].is_busy) { TAILQ_REMOVE(&ipaugenblick_clients_list_head,&ipaugenblick_clients[cmd->ringset_idx],queue_entry); ipaugenblick_clients[cmd->ringset_idx].is_busy = 0; } break; case IPAUGENBLICK_SETSOCKOPT_COMMAND: if(socket_satelite_data[cmd->ringset_idx].socket) { sock_setsockopt(socket_satelite_data[cmd->ringset_idx].socket, cmd->u.setsockopt.level, cmd->u.setsockopt.optname, cmd->u.setsockopt.optval, cmd->u.setsockopt.optlen); } break; case IPAUGENBLICK_SOCKET_SHUTDOWN_COMMAND: if(socket_satelite_data[cmd->ringset_idx].socket) { inet_shutdown(socket_satelite_data[cmd->ringset_idx].socket, cmd->u.socket_shutdown.how); user_sockets_shutdown++; } break; case IPAUGENBLICK_SOCKET_DECLINE_COMMAND: user_flush_rx_tx((struct socket *)cmd->u.socket_decline.socket_descr); app_glue_close_socket((struct socket *)cmd->u.socket_decline.socket_descr); user_sockets_closed++; break; default: ipaugenblick_log(IPAUGENBLICK_LOG_ERR,"unknown cmd %d\n",cmd->cmd); break; } ipaugenblick_free_command_buf(cmd); }