static int create_server_listener(tls_listener_relay_server_type* server) { FUNCSTART; if(!server) return -1; evutil_socket_t tls_listen_fd = -1; tls_listen_fd = socket(server->addr.ss.ss_family, SOCK_STREAM, 0); if (tls_listen_fd < 0) { perror("socket"); return -1; } if(sock_bind_to_device(tls_listen_fd, (unsigned char*)server->ifname)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to device %s\n",server->ifname); } if(addr_bind(tls_listen_fd,&server->addr)<0) { perror("Cannot bind local socket to addr"); char saddr[129]; addr_to_string(&server->addr,(u08bits*)saddr); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind TCP/TLS listener socket to addr %s\n",saddr); socket_closesocket(tls_listen_fd); return -1; } socket_tcp_set_keepalive(tls_listen_fd); socket_set_nonblocking(tls_listen_fd); server->l = evconnlistener_new(server->e->event_base, server_input_handler, server, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 1024, tls_listen_fd); if(!(server->l)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot create TLS listener\n"); socket_closesocket(tls_listen_fd); return -1; } if(addr_get_from_sock(tls_listen_fd, &(server->addr))) { perror("Cannot get local socket addr"); socket_closesocket(tls_listen_fd); return -1; } if(!no_tcp && !no_tls) addr_debug_print(server->verbose, &server->addr,"TCP/TLS listener opened on "); else if(!no_tls) addr_debug_print(server->verbose, &server->addr,"TLS listener opened on "); else if(!no_tcp) addr_debug_print(server->verbose, &server->addr,"TCP listener opened on "); FUNCEND; return 0; }
int socket_create_server(char *bindaddr, int port) { int s = -1; struct addrinfo *p, *servinfo; if (cv_getaddrinfo(bindaddr, port, &servinfo, SOCK_STREAM) == CORVUS_ERR) { LOG(ERROR, "socket_create_server: fail to get address info"); return CORVUS_ERR; } for (p = servinfo; p != NULL; p = p->ai_next) { if ((s = cv_socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { continue; } break; } if (p == NULL || s == -1) { freeaddrinfo(servinfo); return CORVUS_ERR; } if (socket_set_nonblocking(s) == -1) { close(s); freeaddrinfo(servinfo); return CORVUS_ERR; } if (set_reuseaddr(s) == -1) { close(s); freeaddrinfo(servinfo); return CORVUS_ERR; } if (set_reuseport(s) == -1) { close(s); freeaddrinfo(servinfo); return CORVUS_ERR; } if (cv_listen(s, p->ai_addr, p->ai_addrlen, 1024) == -1) { close(s); freeaddrinfo(servinfo); return CORVUS_ERR; } freeaddrinfo(servinfo); return s; }
int conn_create_fd() { int fd = socket_create_stream(); if (fd == -1) { LOG(ERROR, "conn_create_fd: fail to create socket"); return CORVUS_ERR; } if (socket_set_nonblocking(fd) == -1) { LOG(ERROR, "fail to set nonblocking on fd %d", fd); return CORVUS_ERR; } if (socket_set_tcpnodelay(fd) == -1) { LOG(WARN, "fail to set tcpnodelay on fd %d", fd); } return fd; }
static int udp_create_server_socket(server_type* server, const char* ifname, const char *local_address, int port) { FUNCSTART; if(!server) return -1; evutil_socket_t udp_fd = -1; ioa_addr *server_addr = (ioa_addr*)turn_malloc(sizeof(ioa_addr)); STRCPY(server->ifname,ifname); if(make_ioa_addr((const u08bits*)local_address, port, server_addr)<0) return -1; udp_fd = socket(server_addr->ss.ss_family, SOCK_DGRAM, 0); if (udp_fd < 0) { perror("socket"); return -1; } if(sock_bind_to_device(udp_fd, (unsigned char*)server->ifname)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind udp server socket to device %s\n",server->ifname); } set_sock_buf_size(udp_fd,UR_SERVER_SOCK_BUF_SIZE); if(addr_bind(udp_fd,server_addr)<0) return -1; socket_set_nonblocking(udp_fd); struct event *udp_ev = event_new(server->event_base,udp_fd,EV_READ|EV_PERSIST, udp_server_input_handler,server_addr); event_add(udp_ev,NULL); FUNCEND; return 0; }
/* initial socket setup */ bool socket_setup(int sock, bool non_block) { int res; /* close fd on exec */ res = fcntl(sock, F_SETFD, FD_CLOEXEC); if (res < 0) return false; #ifdef SO_NOSIGPIPE /* disallow SIGPIPE, if possible */ val = 1; res = setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val)); if (res < 0) return false; #endif /* when no data available, return EAGAIN instead blocking */ if (!socket_set_nonblocking(sock, non_block)) return false; return true; }
static UA_StatusCode ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl) { ServerNetworkLayerTCP *layer = nl->handle; #ifdef _WIN32 if((layer->serversockfd = socket(PF_INET, SOCK_STREAM,0)) == (UA_Int32)INVALID_SOCKET) { UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, "Error opening socket, code: %d", WSAGetLastError()); return UA_STATUSCODE_BADINTERNALERROR; } #else if((layer->serversockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, "Error opening socket"); return UA_STATUSCODE_BADINTERNALERROR; } #endif const struct sockaddr_in serv_addr = {.sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY, .sin_port = htons(layer->port), .sin_zero = {0}}; int optval = 1; if(setsockopt(layer->serversockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof(optval)) == -1) { UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, "Error during setting of socket options"); CLOSESOCKET(layer->serversockfd); return UA_STATUSCODE_BADINTERNALERROR; } if(bind(layer->serversockfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, "Error during socket binding"); CLOSESOCKET(layer->serversockfd); return UA_STATUSCODE_BADINTERNALERROR; } socket_set_nonblocking(layer->serversockfd); listen(layer->serversockfd, MAXBACKLOG); UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK, "TCP network layer listening on %.*s", nl->discoveryUrl.length, nl->discoveryUrl.data); return UA_STATUSCODE_GOOD; } static size_t ServerNetworkLayerTCP_getJobs(UA_ServerNetworkLayer *nl, UA_Job **jobs, UA_UInt16 timeout) { ServerNetworkLayerTCP *layer = nl->handle; fd_set fdset; UA_Int32 highestfd = setFDSet(layer, &fdset); struct timeval tmptv = {0, timeout}; UA_Int32 resultsize; resultsize = select(highestfd+1, &fdset, NULL, NULL, &tmptv); if(resultsize < 0) { *jobs = NULL; return 0; } /* accept new connections (can only be a single one) */ if(FD_ISSET(layer->serversockfd, &fdset)) { resultsize--; struct sockaddr_in cli_addr; socklen_t cli_len = sizeof(cli_addr); int newsockfd = accept(layer->serversockfd, (struct sockaddr *) &cli_addr, &cli_len); int i = 1; setsockopt(newsockfd, IPPROTO_TCP, TCP_NODELAY, (void *)&i, sizeof(i)); if(newsockfd >= 0) { socket_set_nonblocking(newsockfd); ServerNetworkLayerTCP_add(layer, newsockfd); } } /* alloc enough space for a cleanup-connection and free-connection job per resulted socket */ if(resultsize == 0) return 0; UA_Job *js = malloc(sizeof(UA_Job) * resultsize * 2); if(!js) return 0; /* read from established sockets */ size_t j = 0; UA_ByteString buf = UA_BYTESTRING_NULL; for(size_t i = 0; i < layer->mappingsSize && j < (size_t)resultsize; i++) { if(!(FD_ISSET(layer->mappings[i].sockfd, &fdset))) continue; UA_StatusCode retval = socket_recv(layer->mappings[i].connection, &buf, 0); if(retval == UA_STATUSCODE_GOOD) { UA_Boolean realloced = UA_FALSE; retval = UA_Connection_completeMessages(layer->mappings[i].connection, &buf, &realloced); if(retval != UA_STATUSCODE_GOOD || buf.length == 0) continue; js[j].job.binaryMessage.connection = layer->mappings[i].connection; js[j].job.binaryMessage.message = buf; if(!realloced) js[j].type = UA_JOBTYPE_BINARYMESSAGE_NETWORKLAYER; else js[j].type = UA_JOBTYPE_BINARYMESSAGE_ALLOCATED; j++; } else if (retval == UA_STATUSCODE_BADCONNECTIONCLOSED) { UA_Connection *c = layer->mappings[i].connection; /* the socket was closed from remote */ js[j].type = UA_JOBTYPE_DETACHCONNECTION; js[j].job.closeConnection = layer->mappings[i].connection; layer->mappings[i] = layer->mappings[layer->mappingsSize-1]; layer->mappingsSize--; j++; js[j].type = UA_JOBTYPE_METHODCALL_DELAYED; js[j].job.methodCall.method = FreeConnectionCallback; js[j].job.methodCall.data = c; j++; } } if(j == 0) { free(js); js = NULL; } *jobs = js; return j; }
/* set needed socket options */ void tune_socket(int sock, bool is_unix) { int res; int val; /* close fd on exec */ res = fcntl(sock, F_SETFD, FD_CLOEXEC); if (res < 0) fatal_perror("fcntl FD_CLOEXEC"); /* when no data available, return EAGAIN instead blocking */ socket_set_nonblocking(sock, 1); #ifdef SO_NOSIGPIPE /* disallow SIGPIPE, if possible */ val = 1; res = setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val)); if (res < 0) fatal_perror("setsockopt SO_NOSIGPIPE"); #endif /* * Following options are for network sockets */ if (is_unix) return; /* the keepalive stuff needs some poking before enbling */ if (cf_tcp_keepalive) { /* turn on socket keepalive */ val = 1; res = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); if (res < 0) fatal_perror("setsockopt SO_KEEPALIVE"); #ifdef __linux__ /* set count of keepalive packets */ if (cf_tcp_keepcnt > 0) { val = cf_tcp_keepcnt; res = setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)); if (res < 0) fatal_perror("setsockopt TCP_KEEPCNT"); } /* how long the connection can stay idle before sending keepalive pkts */ if (cf_tcp_keepidle) { val = cf_tcp_keepidle; res = setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)); if (res < 0) fatal_perror("setsockopt TCP_KEEPIDLE"); } /* time between packets */ if (cf_tcp_keepintvl) { val = cf_tcp_keepintvl; res = setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)); if (res < 0) fatal_perror("setsockopt TCP_KEEPINTVL"); } #else #ifdef TCP_KEEPALIVE if (cf_tcp_keepidle) { val = cf_tcp_keepidle; res = setsockopt(sock, IPPROTO_TCP, TCP_KEEPALIVE, &val, sizeof(val)); if (res < 0) fatal_perror("setsockopt TCP_KEEPALIVE"); } #endif #endif } /* set in-kernel socket buffer size */ if (cf_tcp_socket_buffer) { val = cf_tcp_socket_buffer; res = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &val, sizeof(val)); if (res < 0) fatal_perror("setsockopt SO_SNDBUF"); val = cf_tcp_socket_buffer; res = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)); if (res < 0) fatal_perror("setsockopt SO_RCVBUF"); } /* * Turn off kernel buffering, each send() will be one packet. */ val = 1; res = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); if (res < 0) fatal_perror("setsockopt TCP_NODELAY"); }
void tcp_data_connect(app_ur_session *elem, u32bits cid) { int clnet_fd; int connect_cycle = 0; again: clnet_fd = socket(elem->pinfo.remote_addr.ss.sa_family, CLIENT_STREAM_SOCKET_TYPE, CLIENT_STREAM_SOCKET_PROTOCOL); if (clnet_fd < 0) { perror("socket"); exit(-1); } if (sock_bind_to_device(clnet_fd, client_ifname) < 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot bind client socket to device %s\n", client_ifname); } set_sock_buf_size(clnet_fd, (UR_CLIENT_SOCK_BUF_SIZE<<2)); ++elem->pinfo.tcp_conn_number; int i = (int)(elem->pinfo.tcp_conn_number-1); elem->pinfo.tcp_conn=(app_tcp_conn_info**)turn_realloc(elem->pinfo.tcp_conn,0,elem->pinfo.tcp_conn_number*sizeof(app_tcp_conn_info*)); elem->pinfo.tcp_conn[i]=(app_tcp_conn_info*)turn_malloc(sizeof(app_tcp_conn_info)); ns_bzero(elem->pinfo.tcp_conn[i],sizeof(app_tcp_conn_info)); elem->pinfo.tcp_conn[i]->tcp_data_fd = clnet_fd; elem->pinfo.tcp_conn[i]->cid = cid; addr_cpy(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),&(elem->pinfo.local_addr)); addr_set_port(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),0); addr_bind(clnet_fd, &(elem->pinfo.tcp_conn[i]->tcp_data_local_addr), 1, 1, TCP_SOCKET); addr_get_from_sock(clnet_fd,&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr)); { int cycle = 0; while(cycle++<1024) { int err = 0; if (addr_connect(clnet_fd, &(elem->pinfo.remote_addr),&err) < 0) { if(err == EADDRINUSE) { socket_closesocket(clnet_fd); clnet_fd = socket(elem->pinfo.remote_addr.ss.sa_family, CLIENT_STREAM_SOCKET_TYPE, CLIENT_STREAM_SOCKET_PROTOCOL); if (clnet_fd < 0) { perror("socket"); exit(-1); } if (sock_bind_to_device(clnet_fd, client_ifname) < 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot bind client socket to device %s\n", client_ifname); } set_sock_buf_size(clnet_fd, UR_CLIENT_SOCK_BUF_SIZE<<2); elem->pinfo.tcp_conn[i]->tcp_data_fd = clnet_fd; addr_cpy(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),&(elem->pinfo.local_addr)); addr_set_port(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),0); addr_bind(clnet_fd, &(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),1,1,TCP_SOCKET); addr_get_from_sock(clnet_fd,&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr)); continue; } else { perror("connect"); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cannot connect to remote addr\n", __FUNCTION__); exit(-1); } } else { break; } } } if(use_secure) { int try_again = 0; elem->pinfo.tcp_conn[i]->tcp_data_ssl = tls_connect(elem->pinfo.tcp_conn[i]->tcp_data_fd, &(elem->pinfo.remote_addr),&try_again, connect_cycle++); if(!(elem->pinfo.tcp_conn[i]->tcp_data_ssl)) { if(try_again) { --elem->pinfo.tcp_conn_number; goto again; } TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cannot SSL connect to remote addr\n", __FUNCTION__); exit(-1); } } if(turn_tcp_connection_bind(clnet_verbose, &(elem->pinfo), elem->pinfo.tcp_conn[i],0)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cannot BIND to tcp connection\n", __FUNCTION__); } else { socket_set_nonblocking(clnet_fd); struct event* ev = event_new(client_event_base,clnet_fd, EV_READ|EV_PERSIST,client_input_handler, elem); event_add(ev,NULL); elem->input_tcp_data_ev = ev; addr_debug_print(clnet_verbose, &(elem->pinfo.remote_addr), "TCP data network connected to"); } }
static kadm5_ret_t kadm5_s_init_with_context(krb5_context context, const char *client_name, const char *service_name, kadm5_config_params *realm_params, unsigned long struct_version, unsigned long api_version, void **server_handle) { kadm5_ret_t ret; kadm5_server_context *ctx; char *dbname; char *stash_file; ret = _kadm5_s_init_context(&ctx, realm_params, context); if(ret) return ret; if (realm_params->mask & KADM5_CONFIG_DBNAME) dbname = realm_params->dbname; else dbname = ctx->config.dbname; if (realm_params->mask & KADM5_CONFIG_STASH_FILE) stash_file = realm_params->stash_file; else stash_file = ctx->config.stash_file; assert(dbname != NULL); assert(stash_file != NULL); assert(ctx->config.acl_file != NULL); assert(ctx->log_context.log_file != NULL); #ifndef NO_UNIX_SOCKETS assert(ctx->log_context.socket_name.sun_path[0] != '\0'); #else assert(ctx->log_context.socket_info != NULL); #endif ret = hdb_create(ctx->context, &ctx->db, dbname); if(ret) return ret; ret = hdb_set_master_keyfile (ctx->context, ctx->db, stash_file); if(ret) return ret; ctx->log_context.log_fd = -1; #ifndef NO_UNIX_SOCKETS ctx->log_context.socket_fd = socket (AF_UNIX, SOCK_DGRAM, 0); #else ctx->log_context.socket_fd = socket (ctx->log_context.socket_info->ai_family, ctx->log_context.socket_info->ai_socktype, ctx->log_context.socket_info->ai_protocol); #endif socket_set_nonblocking(ctx->log_context.socket_fd, 1); ret = krb5_parse_name(ctx->context, client_name, &ctx->caller); if(ret) return ret; ret = _kadm5_acl_init(ctx); if(ret) return ret; *server_handle = ctx; return 0; }
udp_sender * udp_sender_init( char* addr_str, /*Remote address string*/ int port, /*Remote port*/ config_mngr * cfg ) { assert(MAX_MESSAGE_SIZE <= (MAX_UDP_PAYLOAD+sizeof(lp_message_header))); LOG_MSG(DEBUG, ("Creating sender for UDP address:%s port:%d\n", addr_str, port)); // Create struct to return udp_sender * us = NULL; us = calloc(1, sizeof(udp_sender)); assert(us != NULL); assert(!us->initialized); us->send_buf = NULL; us->is_multicast = false; us->cfg = cfg; //Copy the IP address string assert(addr_str != NULL); if (strlen(addr_str) >= 16 || strlen(addr_str) < 7) { printf("Error: Malformed address %s\n", addr_str); goto udp_sender_init_error; } //Save remote IP memcpy(us->ip_str, addr_str, strlen(addr_str)); us->ip_str[strlen(addr_str)] = '\0'; //Get buffer size and allocate it us->current_buf_size = 0; us->send_buf_size = MAX_UDP_PAYLOAD; us->send_buf = calloc(1, us->send_buf_size); // Create socket and set options us->sock = socket(AF_INET, SOCK_DGRAM, 0); if (us->sock < 0) { perror("socket creation"); goto udp_sender_init_error; } socket_set_reuse_port(us->sock); socket_set_nonblocking(us->sock); if(lpconfig_get_socket_buffers_size(us->cfg)) { socket_set_bufsize(us->sock, lpconfig_get_socket_buffers_size(us->cfg)); } // Configure address and connect bzero(&us->saddr, sizeof(struct sockaddr_in)); us->saddr.sin_family = AF_INET; us->saddr.sin_addr.s_addr = inet_addr(us->ip_str); if (us->saddr.sin_addr.s_addr == INADDR_NONE) { printf("Error: Invalid address %s\n", us->ip_str); goto udp_sender_init_error; } us->saddr.sin_port = htons(port); if (connect(us->sock, (struct sockaddr *)&us->saddr, sizeof(struct sockaddr_in)) < 0) { perror("connect"); goto udp_sender_init_error; } //Stats us->bytes_sent = 0; us->msg_sent = 0; us->last_print_time = time(NULL); us->tot_msg_sent = 0; us->initialized = true; LOG_MSG(INFO, ("Created sender for UDP address %s:%d\n", us->ip_str, port)); return us; udp_sender_init_error: if (us->send_buf != NULL) { free(us->send_buf); } free(us); return NULL; }
udp_receiver * udp_receiver_init( char* addr_str, /*Listen address (optional)*/ int port, /*Listen port*/ handle_datagram_cb cb, /*Callback for packet received*/ void * cb_arg, config_mngr * cfg ) { #ifdef MESSAGE_LOSS_PROBABILITY //Init random seed if the above symbol is defined //(Seeding happens multiple times but it's not relevant...); LOG_MSG(WARNING, ("WARNING: Voluntarily dropping messages with probability %d%%\n", MESSAGE_LOSS_PROBABILITY)); srandom(time(NULL)); #endif LOG_MSG(DEBUG, ("Creating receiver for UDP port %d\n", port)); // Create struct to return udp_receiver * ur = NULL; ur = calloc(1, sizeof(udp_receiver)); assert(ur != NULL); assert(!ur->initialized); //Copy the IP address string if(addr_str != NULL) { assert(strlen(addr_str) < 16); memcpy(ur->ip_str, addr_str, strlen(addr_str)); ur->ip_str[strlen(addr_str)] = '\0'; } //Save the callback invoked when data is received ur->cb = cb; ur->cb_arg = cb_arg; ur->cfg = cfg; //Get buffer size and allocate it ur->recv_buf_size = MAX_UDP_PAYLOAD; ur->recv_buf = calloc(1, ur->recv_buf_size); // Create socket and set options ur->sock = socket(AF_INET, SOCK_DGRAM, 0); if (ur->sock < 0) { perror("socket creation"); return NULL; } socket_set_reuse_port(ur->sock); socket_set_nonblocking(ur->sock); if(lpconfig_get_socket_buffers_size(ur->cfg) > 0) { socket_set_bufsize(ur->sock, lpconfig_get_socket_buffers_size(ur->cfg)); } // Configure address and bind bzero(&ur->saddr, sizeof(struct sockaddr_in)); ur->saddr.sin_family = AF_INET; // If addr_str is non-null, it can be used to bind a specific interface ur->saddr.sin_addr.s_addr = INADDR_ANY; ur->saddr.sin_port = htons(port); if (bind(ur->sock, (struct sockaddr *)&ur->saddr, sizeof(struct sockaddr_in)) < 0) { perror("bind"); return NULL; } // Create receive event event_set(&ur->recv_event, ur->sock, EV_READ|EV_PERSIST, udp_read_callback_wrapper, ur); event_add(&ur->recv_event, NULL); //Bandwidth Statistics ur->bytes_received = 0; ur->msg_received = 0; ur->tot_msg_received = 0; ur->last_print_time = time(NULL); ur->initialized = true; LOG_MSG(INFO, ("Created receiver for UDP port %d\n", port)); return ur; }
static UA_StatusCode ServerNetworkLayerUDP_start(ServerNetworkLayerUDP *layer, UA_Logger logger) { layer->layer.logger = logger; layer->serversockfd = socket(PF_INET, SOCK_DGRAM, 0); if(layer->serversockfd < 0) { UA_LOG_WARNING(layer->layer.logger, UA_LOGCATEGORY_COMMUNICATION, "Error opening socket"); return UA_STATUSCODE_BADINTERNALERROR; } const struct sockaddr_in serv_addr = {.sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY, .sin_port = htons(layer->port), .sin_zero = {0}}; int optval = 1; if(setsockopt(layer->serversockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof(optval)) == -1) { UA_LOG_WARNING(layer->layer.logger, UA_LOGCATEGORY_COMMUNICATION, "Could not setsockopt"); CLOSESOCKET(layer->serversockfd); return UA_STATUSCODE_BADINTERNALERROR; } if(bind(layer->serversockfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { UA_LOG_WARNING(layer->layer.logger, UA_LOGCATEGORY_COMMUNICATION, "Could not bind the socket"); CLOSESOCKET(layer->serversockfd); return UA_STATUSCODE_BADINTERNALERROR; } socket_set_nonblocking(layer->serversockfd); UA_LOG_WARNING(layer->layer.logger, UA_LOGCATEGORY_COMMUNICATION, "Listening for UDP connections on %s:%d", inet_ntoa(serv_addr.sin_addr), ntohs(serv_addr.sin_port)); return UA_STATUSCODE_GOOD; } static size_t ServerNetworkLayerUDP_getJobs(ServerNetworkLayerUDP *layer, UA_Job **jobs, UA_UInt16 timeout) { UA_Job *items = NULL; setFDSet(layer); struct timeval tmptv = {0, timeout}; UA_Int32 resultsize = select(layer->serversockfd+1, &layer->fdset, NULL, NULL, &tmptv); if(resultsize <= 0 || !FD_ISSET(layer->serversockfd, &layer->fdset)) { *jobs = items; return 0; } items = malloc(sizeof(UA_Job)*resultsize); // read from established sockets UA_Int32 j = 0; UA_ByteString buf = {-1, NULL}; if(!buf.data) { buf.data = malloc(sizeof(UA_Byte) * layer->conf.recvBufferSize); if(!buf.data) UA_LOG_WARNING(layer->layer.logger, UA_LOGCATEGORY_COMMUNICATION, "malloc failed"); } struct sockaddr sender; socklen_t sendsize = sizeof(sender); bzero(&sender, sizeof(sender)); buf.length = recvfrom(layer->serversockfd, buf.data, layer->conf.recvBufferSize, 0, &sender, &sendsize); if (buf.length <= 0) { } else { UDPConnection *c = malloc(sizeof(UDPConnection)); if(!c) return UA_STATUSCODE_BADINTERNALERROR; UA_Connection_init(&c->connection); c->from = sender; c->fromlen = sendsize; // c->sockfd = newsockfd; c->connection.getSendBuffer = GetMallocedBuffer; c->connection.releaseSendBuffer = ReleaseMallocedBuffer; c->connection.releaseRecvBuffer = ReleaseMallocedBuffer; c->connection.handle = layer; c->connection.send = sendUDP; c->connection.close = closeConnectionUDP; c->connection.localConf = layer->conf; c->connection.state = UA_CONNECTION_OPENING; items[j].type = UA_JOBTYPE_BINARYMESSAGE_NETWORKLAYER; items[j].job.binaryMessage.message = buf; items[j].job.binaryMessage.connection = (UA_Connection*)c; buf.data = NULL; j++; } if(buf.data) free(buf.data); if(j == 0) { free(items); *jobs = NULL; } else *jobs = items; return j; }