0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <ndrx_config.h>
0037 #include <sys/socket.h>
0038 #include <sys/time.h>
0039 #include <sys/types.h>
0040 #include <arpa/inet.h>
0041 #include <netinet/in.h>
0042 #include <errno.h>
0043 #include <fcntl.h>
0044 #include <netdb.h>
0045 #include <string.h>
0046 #include <unistd.h>
0047 #include <atmi.h>
0048
0049 #include <stdio.h>
0050 #include <stdlib.h>
0051
0052 #include <exnet.h>
0053 #include <ndrstandard.h>
0054 #include <ndebug.h>
0055 #include <userlog.h>
0056
0057 #if defined(EX_USE_EPOLL)
0058
0059 #include <sys/epoll.h>
0060
0061 #elif defined(EX_USE_KQUEUE)
0062
0063 #include <sys/event.h>
0064
0065 #else
0066
0067 #include <poll.h>
0068
0069 #endif
0070
0071
0072
0073 #if defined(EX_USE_EPOLL)
0074
0075
0076
0077
0078
0079 #define POLL_FLAGS (EPOLLIN | EPOLLHUP)
0080
0081 #elif defined (EX_USE_KQUEUE)
0082
0083 #define POLL_FLAGS EVFILT_READ
0084
0085 #else
0086
0087 #define POLL_FLAGS POLLIN
0088
0089 #endif
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 expublic void exnet_remove_incoming(exnetcon_t *net)
0102 {
0103
0104 net->my_server->incomming_cons--;
0105 NDRX_LOG(log_debug, "Open connections decreased to: %d",
0106 net->my_server->incomming_cons);
0107
0108
0109
0110 }
0111
0112
0113
0114
0115
0116
0117 expublic int exnetsvpollevent(int fd, uint32_t events, void *ptr1)
0118 {
0119 int ret=EXSUCCEED;
0120 exnetcon_t *srv = (exnetcon_t *)ptr1;
0121 struct sockaddr_in clt_address;
0122 int client_fd;
0123 const char * ip_ptr;
0124 exnetcon_t *client = NULL;
0125 char *fn = "exnetsvpollevent";
0126 socklen_t addr_len = sizeof(clt_address);
0127 int is_new_con;
0128 int port;
0129 char ip[(INET6_ADDRSTRLEN)*2];
0130 struct sockaddr *sa = (struct sockaddr *)&clt_address;
0131
0132 #define CLT_COMMON_SETUP client->sock = client_fd;\
0133 EXNET_CONNECTED(client);\
0134 \
0135
0136
0137 \
0138 \
0139 if((ip_ptr = inet_ntop(sa->sa_family, &clt_address.sin_addr, ip, sizeof(ip))) < 0 )\
0140 {\
0141 NDRX_LOG(log_error, "Failed to get client IP address! %s", \
0142 strerror(errno));\
0143 ret=EXFAIL;\
0144 }\
0145 \
0146 NDRX_STRCPY_SAFE(client->addr, ip_ptr);\
0147 \
0148 port = ntohs(clt_address.sin_port);\
0149 NDRX_LOG(log_warn, "Got call from: %s:%u", client->addr, port);\
0150 \
0151 if (EXSUCCEED!=exnet_configure_setopts(client))\
0152 {\
0153 NDRX_LOG(log_error, "Failed to configure client socket");\
0154 ret=EXFAIL;\
0155 }
0156
0157
0158 NDRX_LOG(log_debug, "%s - enter", fn);
0159
0160
0161 if ( (client_fd = accept(srv->sock, (struct sockaddr *)&clt_address, &addr_len) ) < 0 )
0162 {
0163 NDRX_LOG(log_error, "Error calling accept(): %s", strerror(errno));
0164 EXFAIL_OUT(ret);
0165 }
0166
0167 NDRX_LOG(log_error, "New incoming connection: fd=%d", client_fd);
0168
0169 if (srv->incomming_cons+1 > srv->max_cons)
0170 {
0171 NDRX_LOG(log_error, "Too many open connections: %d/%d - closing down fd %d",
0172 srv->incomming_cons+1, srv->max_cons, client_fd);
0173 close(client_fd);
0174
0175 goto out;
0176 }
0177 srv->incomming_cons++;
0178 NDRX_LOG(log_debug, "Open connections increased to: %d",
0179 srv->incomming_cons);
0180
0181
0182
0183
0184
0185 if (NULL!=(client=exnet_find_free_conn()))
0186 {
0187 NDRX_LOG(log_info, "Reusing connection object");
0188 is_new_con = EXFALSE;
0189 }
0190 else
0191 {
0192 NDRX_LOG(log_info, "Creating new connection object");
0193 is_new_con = EXTRUE;
0194 }
0195
0196 if (is_new_con)
0197 {
0198 if (NULL==(client = NDRX_MALLOC(sizeof(exnetcon_t))))
0199 {
0200 int err = errno;
0201
0202 userlog("Failed to allocate client structure! %s",
0203 strerror(err));
0204
0205 NDRX_LOG(log_error, "Failed to allocate client structure! %s",
0206 strerror(err));
0207 EXFAIL_OUT(ret);
0208 }
0209
0210 memcpy(client, srv, sizeof(exnetcon_t));
0211
0212
0213 client->is_server=EXFALSE;
0214 client->is_incoming = EXTRUE;
0215 client->my_server = srv;
0216
0217 memcpy(&client->address, &clt_address, sizeof(clt_address));
0218
0219
0220 CLT_COMMON_SETUP;
0221
0222
0223 if (EXSUCCEED!=ret)
0224 {
0225 goto out;
0226 }
0227
0228 if (EXSUCCEED!=exnet_net_init(client))
0229 {
0230 NDRX_LOG(log_error, "Failed to init client!");
0231 EXFAIL_OUT(ret);
0232 }
0233 }
0234 else
0235 {
0236 exnet_rwlock_mainth_write(client);
0237
0238 CLT_COMMON_SETUP;
0239
0240 exnet_rwlock_mainth_read(client);
0241
0242
0243 if (EXSUCCEED!=ret)
0244 {
0245 goto out;
0246 }
0247 }
0248
0249
0250
0251 if (NULL!=client->p_connected && EXSUCCEED!=client->p_connected(client))
0252 {
0253 NDRX_LOG(log_error, "Connected notification "
0254 "callback failed!");
0255 EXFAIL_OUT(ret);
0256 }
0257
0258
0259 if (EXSUCCEED!=tpext_addpollerfd(client->sock, POLL_FLAGS,
0260 client, exnet_poll_cb))
0261 {
0262 NDRX_LOG(log_error, "tpext_addpollerfd failed!");
0263 ret=EXFAIL;
0264 goto out;
0265 }
0266
0267 if (is_new_con)
0268 {
0269 NDRX_LOG(log_info, "Adding connection to hashlist");
0270
0271 exnet_add_con(client);
0272 }
0273
0274 out:
0275
0276 if (EXSUCCEED!=ret && client)
0277 {
0278 NDRX_FREE(client);
0279 }
0280
0281 NDRX_LOG(log_debug, "%s - return %d", fn, ret);
0282
0283 return ret;
0284 }
0285
0286
0287
0288
0289
0290
0291
0292
0293 expublic int exnet_bind(exnetcon_t *net)
0294 {
0295 int ret=EXSUCCEED;
0296 char *fn = "exnet_bind";
0297 char ip[(INET6_ADDRSTRLEN)*2];
0298
0299 NDRX_LOG(log_debug, "%s - enter", fn);
0300
0301 if ( (net->sock = socket(net->addr_cur->ai_family, SOCK_STREAM, 0)) < 0 )
0302 {
0303 NDRX_LOG(log_error, "Failed to create socket: %s",
0304 strerror(errno));
0305 EXFAIL_OUT(ret);
0306 }
0307
0308 if (EXSUCCEED!=exnet_configure_setopts(net))
0309 {
0310 NDRX_LOG(log_error, "Failed to set socket opts!");
0311 EXFAIL_OUT(ret);
0312 }
0313
0314 if (NULL!=inet_ntop (net->addr_cur->ai_family,
0315 &((struct sockaddr_in *)net->addr_cur->ai_addr)->sin_addr, ip, sizeof(ip)))
0316 {
0317 NDRX_LOG(log_info,"About to listen on IPv%d address: %s port: %d",
0318 net->addr_cur->ai_family == PF_INET6 ? 6 : 4, ip,
0319 (int)exnet_get_port(net->addr_cur->ai_addr));
0320 }
0321 else
0322 {
0323 NDRX_LOG(log_error, "Failed to listen address info: %s", strerror(errno));
0324 }
0325
0326
0327
0328
0329 if ( bind(net->sock, net->addr_cur->ai_addr, (int)net->addr_cur->ai_addrlen) < 0 )
0330 {
0331 if (errno==EADDRINUSE || errno==EADDRNOTAVAIL)
0332 {
0333 NDRX_LOG(log_error, "Error calling bind(): %s - ignore error, try later",
0334 strerror(errno));
0335 close(net->sock);
0336 net->sock=EXFAIL;
0337 goto out;
0338 }
0339 else
0340 {
0341 NDRX_LOG(log_error, "Error calling bind(): %s", strerror(errno));
0342 EXFAIL_OUT(ret);
0343 }
0344
0345 }
0346
0347 if ( listen(net->sock, net->backlog) < 0 )
0348 {
0349 if (errno==EADDRINUSE)
0350 {
0351 NDRX_LOG(log_error, "Error calling listen(): %s - ignore error, try later",
0352 strerror(errno));
0353
0354 close(net->sock);
0355 net->sock=EXFAIL;
0356 goto out;
0357 }
0358 else
0359 {
0360 NDRX_LOG(log_error, "Error calling listen(): %s",
0361 strerror(errno));
0362 EXFAIL_OUT(ret);
0363 }
0364 }
0365
0366
0367 if (EXSUCCEED!=tpext_addpollerfd(net->sock, POLL_FLAGS, net, exnetsvpollevent))
0368 {
0369 NDRX_LOG(log_error, "tpext_addpollerfd failed!");
0370 ret=EXFAIL;
0371 goto out;
0372 }
0373
0374 out:
0375
0376 NDRX_LOG(log_debug, "%s - return %d", fn, ret);
0377
0378 return ret;
0379 }
0380