예제 #1
0
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;
}
예제 #2
0
파일: socket.c 프로젝트: BBGIP/corvus
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
파일: socket.c 프로젝트: mpihlak/libusual
/* 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;
}
예제 #6
0
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;
}
예제 #7
0
파일: util.c 프로젝트: fdr/pgbouncer-cvs
/* 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");
}
예제 #8
0
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");
	}
}
예제 #9
0
파일: init_s.c 프로젝트: InvLim/heimdal
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;
}
예제 #10
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;
}
예제 #11
0
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;
    }
예제 #12
0
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;
}