Definition in file tcp_accept.c.
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include "utils.h"
#include "globals.h"
#include "tcp_accept.h"
#include "receiver.h"
Go to the source code of this file.
Functions | |
| int | dp_add_pid (pid_t pid) |
| Add a pid to the local process list. | |
| int | create_socket (int listen_port, str bind_to, unsigned int *sock) |
| Creates a socket and binds it. | |
| static int | accept_connection (int server_sock, int *new_sock) |
| Accepts an incoming connection by forking a receiver process. | |
| void | accept_loop () |
| Accept loop that listens for incoming connections on all listening sockets. | |
Variables | |
| unsigned int * | listening_socks = 0 |
| array of sockets listening for connections | |
| int | h_errno |
| int dp_add_pid | ( | pid_t | pid | ) | [inline] |
Add a pid to the local process list.
| pid | newly forked pid |
Definition at line 95 of file diameter_peer.c.
00096 { 00097 pid_list_t *n; 00098 lock_get(pid_list_lock); 00099 n = shm_malloc(sizeof(pid_list_t)); 00100 if (!n){ 00101 LOG_NO_MEM("shm",sizeof(pid_list_t)); 00102 lock_release(pid_list_lock); 00103 return 0; 00104 } 00105 n->pid = pid; 00106 n->next = 0; 00107 n->prev = pid_list->tail; 00108 if (!pid_list->head) pid_list->head = n; 00109 if (pid_list->tail) pid_list->tail->next = n; 00110 pid_list->tail = n; 00111 lock_release(pid_list_lock); 00112 return 1; 00113 }
| int create_socket | ( | int | listen_port, | |
| str | bind_to, | |||
| unsigned int * | sock | |||
| ) |
Creates a socket and binds it.
| listen_port | - port to listen to | |
| bind_to | - IP address to bind to - if empty, will bind to :: (0.0.0.0) (all) | |
| sock | - socket to be update with the identifier of the opened one |
Definition at line 91 of file tcp_accept.c.
Referenced by acceptor_process().
00092 { 00093 unsigned int server_sock=-1; 00094 struct addrinfo *ainfo=0,*res=0,hints; 00095 char buf[256],host[256],serv[256]; 00096 int error=0; 00097 unsigned int option; 00098 00099 memset (&hints, 0, sizeof(hints)); 00100 //hints.ai_protocol = IPPROTO_SCTP; 00101 //hints.ai_protocol = IPPROTO_TCP; 00102 hints.ai_flags = AI_PASSIVE|AI_ADDRCONFIG; 00103 hints.ai_socktype = SOCK_STREAM; 00104 00105 sprintf(buf,"%d",listen_port); 00106 00107 if (bind_to.len){ 00108 error = getaddrinfo(bind_to.s, buf, &hints, &res); 00109 if (error!=0){ 00110 LOG(L_WARN,"WARNING:create_socket(): Error opening %.*s port %d while doing gethostbyname >%s\n", 00111 bind_to.len,bind_to.s,listen_port,gai_strerror(error)); 00112 goto error; 00113 } 00114 }else{ 00115 error = getaddrinfo(NULL, buf, &hints, &res); 00116 if (error!=0){ 00117 LOG(L_WARN,"WARNING:create_socket(): Error opening ANY port %d while doing gethostbyname >%s\n", 00118 listen_port,gai_strerror(error)); 00119 goto error; 00120 } 00121 } 00122 00123 LOG(L_DBG,"DBG:create_sockets: create socket and bind for IPv4...\n"); 00124 00125 for(ainfo = res;ainfo;ainfo = ainfo->ai_next) 00126 { 00127 if (getnameinfo(ainfo->ai_addr,ainfo->ai_addrlen, 00128 host,256,serv,256,NI_NUMERICHOST|NI_NUMERICSERV)==0){ 00129 LOG(L_WARN,"INFO:create_socket(): Trying to open/bind/listen on %s port %s\n", 00130 host,serv); 00131 } 00132 00133 if ((server_sock = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol)) == -1) { 00134 LOG(L_ERR,"ERROR:create_socket(): error creating server socket on %s port %s >" 00135 " %s\n",host,serv,strerror(errno)); 00136 goto error; 00137 } 00138 option = 1; 00139 setsockopt(server_sock,SOL_SOCKET,SO_REUSEADDR,&option,sizeof(option)); 00140 00141 if (bind( server_sock,ainfo->ai_addr,ainfo->ai_addrlen)==-1 ) { 00142 LOG(L_ERR,"ERROR:create_socket(): error binding on %s port %s >" 00143 " %s\n",host,serv,strerror(errno)); 00144 goto error; 00145 } 00146 00147 if (listen( server_sock, 5) == -1) { 00148 LOG(L_ERR,"ERROR:create_socket(): error listening on %s port %s > %s\n",host,serv,strerror(errno) ); 00149 goto error; 00150 } 00151 00152 *sock = server_sock; 00153 00154 LOG(L_WARN,"INFO:create_socket(): Successful socket open/bind/listen on %s port %s\n", 00155 host,serv); 00156 } 00157 if (res) freeaddrinfo(res); 00158 return 1; 00159 error: 00160 if (res) freeaddrinfo(res); 00161 if (server_sock!=-1) close(server_sock); 00162 return 0; 00163 00164 }
| static int accept_connection | ( | int | server_sock, | |
| int * | new_sock | |||
| ) | [inline, static] |
Accepts an incoming connection by forking a receiver process.
| server_sock | - socket that this connection came in to | |
| new_sock | - socket to be update with the value of the accepter socket |
Definition at line 172 of file tcp_accept.c.
References dp_add_pid(), errno, listening_socks, receiver_init(), and receiver_process().
Referenced by accept_loop().
00173 { 00174 unsigned int length; 00175 struct sockaddr_in remote; 00176 int pid; 00177 00178 /* do accept */ 00179 length = sizeof( struct sockaddr_in); 00180 *new_sock = accept( server_sock, (struct sockaddr*)&remote, &length); 00181 00182 if (*new_sock==-1) { 00183 LOG(L_ERR,"ERROR:accept_connection(): accept failed!\n"); 00184 goto error; 00185 } else { 00186 LOG(L_INFO,"INFO:accept_connection(): new tcp connection accepted!\n"); 00187 00188 } 00189 00190 receiver_init(*new_sock,0); 00191 00192 #ifdef CDP_FOR_SER 00193 pid = fork_process(server_sock,"receiver R",0); 00194 #else 00195 pid = fork(); 00196 #endif 00197 if (pid<0){ 00198 LOG(L_ERR,"ERROR:accept_connection(): fork() failed > %s\n",strerror(errno)); 00199 goto error; 00200 } 00201 if (pid==0){ 00202 /* child */ 00203 if (listening_socks) { 00204 pkg_free(listening_socks); 00205 listening_socks=0; 00206 } 00207 dp_add_pid(pid); 00208 receiver_process(*new_sock); 00209 LOG(L_CRIT,"ERROR:accept_connection(): receiver_process finished without exit!\n"); 00210 exit(-1); 00211 }else{ 00212 /* parent */ 00213 LOG(L_INFO,"INFO:accept_connection(): Receiver process forked [%d]\n",pid); 00214 } 00215 00216 return 1; 00217 error: 00218 return 0; 00219 }
| void accept_loop | ( | ) |
Accept loop that listens for incoming connections on all listening sockets.
When a connection is received, accept_connection() is called.
Definition at line 226 of file tcp_accept.c.
References accept_connection(), errno, listening_socks, select, and shutdownx.
00227 { 00228 fd_set listen_set; 00229 struct timeval timeout; 00230 int i=0,max_sock=0,nready; 00231 int new_sock; 00232 00233 00234 while(listening_socks[i]){ 00235 if (listening_socks[i]>max_sock) max_sock=listening_socks[i]; 00236 i++; 00237 } 00238 00239 while(1){ 00240 if (shutdownx && *shutdownx) break; 00241 00242 timeout.tv_sec=2; 00243 timeout.tv_usec=0; 00244 FD_ZERO(&listen_set); 00245 i=0; 00246 while(listening_socks[i]){ 00247 FD_SET(listening_socks[i],&listen_set); 00248 i++; 00249 } 00250 00251 nready = select( max_sock+1, &listen_set, 0, 0, &timeout); 00252 if (nready == 0){ 00253 LOG(L_DBG,"DBG:accept_loop(): No connection attempts\n"); 00254 continue; 00255 } 00256 if (nready == -1) { 00257 if (errno == EINTR) { 00258 continue; 00259 } else { 00260 LOG(L_ERR,"ERROR:accept_loop(): select fails: %s\n", 00261 strerror(errno)); 00262 sleep(2); 00263 continue; 00264 } 00265 } 00266 00267 i=0; 00268 while(listening_socks[i]){ 00269 if (FD_ISSET(listening_socks[i],&listen_set)){ 00270 accept_connection(listening_socks[i],&new_sock); 00271 } 00272 i++; 00273 } 00274 } 00275 }
| unsigned int* listening_socks = 0 |
array of sockets listening for connections
Definition at line 79 of file tcp_accept.c.
Referenced by accept_connection(), accept_loop(), and acceptor_process().
| int h_errno |
1.5.2