Example #1
0
static int proc_data_send(struct client *cl, const char *data, int len)
{
	struct dispatch_proc *p = &cl->dispatch.proc;
	int retlen = 0;
	int ret;

	while (len) {
		ret = write(p->wrfd.fd, data, len);

		if (ret < 0) {
			if (errno == EINTR)
				continue;

			if (errno == EAGAIN || errno == EWOULDBLOCK)
				break;

			/* consume all data */
			ret = len;
		}

		if (!ret)
			break;

		retlen += ret;
		len -= ret;
		data += ret;
	}

	if (len)
		uloop_fd_add(&p->wrfd, ULOOP_WRITE);
	else
		uloop_fd_delete(&p->wrfd);

	return retlen;
}
Example #2
0
int
UBusThread::run()
{
    ILOG_TRACE(UBUS_THREAD);
    uloop_fd_add(&_ubus_fd, ULOOP_READ);
    uloop_run();
    return 0;
}
int main(int argc, char **argv)
{
  struct dummy_struct ds;
  int c;
  int type = kDNSServiceType_ANY;
  int flags = 0;
  int ifindex = 0;

  memset (&ds, 0, sizeof(ds));
  while ((c = getopt(argc, argv, "f:t:i:")) != -1)
    switch (c)
      {
      case 't':
        type = atoi(optarg);
        break;
      case 'i':
        ifindex = if_nametoindex(optarg);
        break;
      case 'f':
        flags = atoi(optarg);
        break;
      }
  if (argc <= 1)
    {
      fprintf(stderr, "Usage: %s [-f <flags>] [-i <if>] [-t <type>] <name>\n",
              argv[0]);
      exit(1);
    }
  if (DNSServiceQueryRecord(&ds.service, flags, ifindex,
                            argv[1],
                            type,
                            kDNSServiceClass_IN,
                            dummy_callback,
                            NULL) != kDNSServiceErr_NoError)
    {
      fprintf(stderr, "Error initializing DNSServiceQueryRecord\n");
      exit(1);
    }

  if (uloop_init() < 0)
    {
      fprintf(stderr, "Error in uloop_init\n");
      exit(1);
    }
  ds.ufd.fd = DNSServiceRefSockFD(ds.service);
  printf("FD:%d\n", ds.ufd.fd);
  ds.ufd.cb = uloop_fd_callback;
  if (uloop_fd_add(&ds.ufd, ULOOP_READ) < 0)
    {
      fprintf(stderr, "Error in uloop_fd_add\n");
      exit(1);
    }
  printf("Entering event loop\n");
  uloop_run();
  return 0;
}
Example #4
0
static void log_handle_reconnect(struct uloop_timeout *timeout)
{
	sender.fd = usock((log_udp) ? (USOCK_UDP) : (USOCK_TCP), log_ip, log_port);
	if (sender.fd < 0) {
		fprintf(stderr, "failed to connect: %s\n", strerror(errno));
		uloop_timeout_set(&retry, 1000);
	} else {
		uloop_fd_add(&sender, ULOOP_READ);
		syslog(LOG_INFO, "Logread connected to %s:%s\n", log_ip, log_port);
	}
}
Example #5
0
bool hncp_io_init(hncp o)
{
  int s;
  int on = 1;
  int off = 0;
#if 0
  /* Could also use usock here; however, it uses getaddrinfo, which
   * doesn't seem to work when e.g. default routes aren't currently
   * set up. Too bad. */
  char buf[6];

  sprintf(buf, "%d", HNCP_PORT);
  s = usock(USOCK_IPV6ONLY|USOCK_UDP|USOCK_SERVER|USOCK_NONBLOCK, NULL, buf);
  if (s < 0)
    return false;
#else
  struct sockaddr_in6 addr;

  s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
  if (s<0) {
    L_ERR("unable to create IPv6 UDP socket");
    return false;
  }
  fcntl(s, F_SETFL, O_NONBLOCK);
  memset(&addr, 0, sizeof(addr));
  addr.sin6_family = AF_INET6;
  addr.sin6_port = htons(HNCP_PORT);
  const int one = 1;
  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
  if (bind(s, (struct sockaddr *)&addr, sizeof(addr))<0) {
    L_ERR("unable to bind to port %d", HNCP_PORT);
    return false;
  }
#endif
  if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)) < 0)
    {
      L_ERR("unable to setsockopt IPV6_RECVPKTINFO:%s", strerror(errno));
      return false;
    }
  if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, sizeof(off)) < 0)
    {
      L_ERR("unable to setsockopt IPV6_MULTICAST_LOOP:%s", strerror(errno));
      return false;
    }
  o->udp_socket = s;
  o->timeout.cb = _timeout;

  memset(&o->ufd, 0, sizeof(o->ufd));
  o->ufd.fd = o->udp_socket;
  o->ufd.cb = _fd_callback;
  uloop_fd_add(&o->ufd, ULOOP_READ);
  return true;
}
Example #6
0
void u_tcp_connect()
{
    usfd.stream.write_error = 1;

	ufd.fd = usock(USOCK_TCP, u_tcp_host, u_tcp_port);
	if (ufd.fd < 0) {
		_debug("connection to sysrepo failed"); 
		uloop_timeout_set(&reconnect_timer, 1000);
	}

	ufd.cb = connect_cb;
	uloop_fd_add(&ufd, ULOOP_WRITE | ULOOP_EDGE_TRIGGER);
}
Example #7
0
static void ustream_fd_set_uloop(struct ustream *s, bool write)
{
	struct ustream_fd *sf = container_of(s, struct ustream_fd, stream);
	struct ustream_buf *buf;
	unsigned int flags = ULOOP_EDGE_TRIGGER | ULOOP_ERROR_CB;

	if (!s->read_blocked && !s->eof)
		flags |= ULOOP_READ;

	buf = s->w.head;
	if (write || (buf && s->w.data_bytes && !s->write_error))
		flags |= ULOOP_WRITE;

	uloop_fd_add(&sf->fd, flags);
}
Example #8
0
int main(void)
{

	jrpc_server_init(&my_server, HOST, PORT);
	jrpc_register_procedure(&my_server, say_hello, "sayHello", NULL);
	jrpc_register_procedure(&my_server, exit_server, "exit", NULL);
	jrpc_register_procedure(&my_server, foo, "foo", NULL);

	uloop_init();
	uloop_fd_add(&my_server.sock, ULOOP_READ);
	uloop_run();

	jrpc_server_destroy(&my_server);

	return 0;
}
Example #9
0
static void
reconnect_socket6(struct uloop_timeout *timeout)
{
	struct interface *iface = container_of(timeout, struct interface, reconnect);
	char mcast_addr[128];
	int ttl = 255;
	int yes = 1;

	snprintf(mcast_addr, sizeof(mcast_addr), "%s%%%s", (iface->multicast) ? (iface->mcast_addr) : (iface->v6_addrs), iface->name);
	iface->fd.fd = usock(USOCK_UDP | USOCK_SERVER | USOCK_NONBLOCK | USOCK_IPV6ONLY, mcast_addr, "5353");
	if (iface->fd.fd < 0) {
		fprintf(stderr, "failed to add listener %s: %s\n", mcast_addr, strerror(errno));
		goto retry;
	}

	if (setsockopt(iface->fd.fd, SOL_SOCKET, SO_BINDTODEVICE, iface->name, strlen(iface->name) < 0))
		fprintf(stderr, "ioctl failed: SO_BINDTODEVICE\n");

	if (setsockopt(iface->fd.fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) < 0)
		fprintf(stderr, "ioctl failed: IPV6_UNICAST_HOPS\n");

	if (setsockopt(iface->fd.fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &yes, sizeof(yes)) < 0)
		fprintf(stderr, "ioctl failed: IPV6_RECVPKTINFO\n");

	if (setsockopt(iface->fd.fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &yes, sizeof(yes)) < 0)
		fprintf(stderr, "ioctl failed: IPV6_RECVHOPLIMIT\n");

	if (setsockopt(iface->fd.fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
		fprintf(stderr, "ioctl failed: SO_REUSEADDR\n");

	if (iface->multicast && interface_socket_setup6(iface)) {
		iface->fd.fd = -1;
		goto retry;
	}

	uloop_fd_add(&iface->fd, ULOOP_READ);

	if (iface->multicast) {
		dns_send_question(iface, "_services._dns-sd._udp.local", TYPE_PTR, 1);
		announce_init(iface);
	}

	return;

retry:
	uloop_timeout_set(timeout, 1000);
}
Example #10
0
static int netlink_init(void)
{
	struct {
		struct nlmsghdr hdr;
		struct ifaddrmsg msg;
	} req;
	struct sockaddr_nl addr;
	int sock[2];

	memset(&addr, 0, sizeof(addr));
	memset(&req, 0, sizeof(req));

	if ((sock[0] = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) {
		D("couldn't open NETLINK_ROUTE socket");
		return -1;
	}

	addr.nl_family = AF_NETLINK;
	addr.nl_groups = RTMGRP_IPV4_IFADDR;
	if ((bind(sock[0], (struct sockaddr *)&addr, sizeof(addr))) == -1) {
		D("couldn't bind netlink socket");
		return -1;
	}

	netlink_event.fd = sock[0];
	uloop_fd_add(&netlink_event, ULOOP_READ | ULOOP_EDGE_TRIGGER);

	if ((sock[1] = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) == -1) {
		D("couldn't open NETLINK_ROUTE socket");
		return -1;
	}

	req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
	req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
	req.hdr.nlmsg_type = RTM_GETADDR;
	req.msg.ifa_family = AF_INET;

	if ((send(sock[1], &req, req.hdr.nlmsg_len, 0)) == -1) {
		D("couldn't send netlink socket");
		return -1;
	}

	struct uloop_fd dummy_event = { .fd = sock[1] };
	netlink_new_msg(&dummy_event, 0);

	return 0;
}
Example #11
0
void
http_server_init(void)
{
	http_digest_init_nonce_priv_key();

	http_s.http_event.cb = http_new_client;

	http_s.http_event.fd = usock(USOCK_TCP | USOCK_SERVER, "0.0.0.0", config->local->port);
	uloop_fd_add(&http_s.http_event, ULOOP_READ | ULOOP_EDGE_TRIGGER);

	DDF("+++ HTTP SERVER CONFIGURATION +++\n");
	if (config->local->ip)
		DDF("ip: '%s'\n", config->local->ip);
	else
		DDF("NOT BOUND TO IP\n");
	DDF("port: '%s'\n", config->local->port);
	DDF("--- HTTP SERVER CONFIGURATION ---\n");

	log_message(NAME, L_NOTICE, "http server initialized\n");
}
Example #12
0
static void
reconnect_socket4(struct uloop_timeout *timeout)
{
	struct interface *iface = container_of(timeout, struct interface, reconnect);
	int yes = 1;

	iface->fd.fd = usock(USOCK_UDP | USOCK_SERVER | USOCK_NONBLOCK | USOCK_IPV4ONLY,
		(iface->multicast) ? (iface->mcast_addr) : (iface->v4_addrs), "5353");
	if (iface->fd.fd < 0) {
		fprintf(stderr, "failed to add listener %s: %s\n", iface->mcast_addr, strerror(errno));
		goto retry;
	}

	if (setsockopt(iface->fd.fd, SOL_SOCKET, SO_BINDTODEVICE, iface->name, strlen(iface->name) < 0))
		fprintf(stderr, "ioctl failed: SO_BINDTODEVICE\n");

	if (setsockopt(iface->fd.fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
		fprintf(stderr, "ioctl failed: SO_REUSEADDR\n");

	if (setsockopt(iface->fd.fd, IPPROTO_IP, IP_RECVTTL, &yes, sizeof(yes)) < 0)
		fprintf(stderr, "ioctl failed: IP_RECVTTL\n");

	if (setsockopt(iface->fd.fd, IPPROTO_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0)
		fprintf(stderr, "ioctl failed: IP_PKTINFO\n");

	if (iface->multicast && interface_mcast_setup4(iface)) {
		iface->fd.fd = -1;
		goto retry;
	}

	uloop_fd_add(&iface->fd, ULOOP_READ);
	if (iface->multicast) {
		dns_send_question(iface, "_services._dns-sd._udp.local", TYPE_PTR, 1);
		announce_init(iface);
	}

	return;

retry:
	uloop_timeout_set(timeout, 1000);
}
Example #13
0
int main(int argc, char **argv)
{
	const char *ubus_socket = UBUS_UNIX_SOCKET;
	int ret = 0;
	int ch;

	signal(SIGPIPE, SIG_IGN);
	signal(SIGHUP, sighup_handler);

	openlog("ubusd", LOG_PID, LOG_DAEMON);
	uloop_init();

	while ((ch = getopt(argc, argv, "s:")) != -1) {
		switch (ch) {
		case 's':
			ubus_socket = optarg;
			break;
		default:
			return usage(argv[0]);
		}
	}

	unlink(ubus_socket);
	umask(0111);
	server_fd.fd = usock(USOCK_UNIX | USOCK_SERVER | USOCK_NONBLOCK, ubus_socket, NULL);
	if (server_fd.fd < 0) {
		perror("usock");
		ret = -1;
		goto out;
	}
	uloop_fd_add(&server_fd, ULOOP_READ | ULOOP_EDGE_TRIGGER);
	ubusd_acl_load();

	uloop_run();
	unlink(ubus_socket);

out:
	uloop_done();
	return ret;
}
Example #14
0
/* takes the msgbuf reference */
void ubus_msg_send(struct ubus_client *cl, struct ubus_msg_buf *ub, bool free)
{
	int written;

	if (!cl->tx_queue[cl->txq_cur]) {
		written = ubus_msg_writev(cl->sock.fd, ub, 0);
		if (written >= ub->len + sizeof(ub->hdr))
			goto out;

		if (written < 0)
			written = 0;

		cl->txq_ofs = written;

		/* get an event once we can write to the socket again */
		uloop_fd_add(&cl->sock, ULOOP_READ | ULOOP_WRITE | ULOOP_EDGE_TRIGGER);
	}
	ubus_msg_enqueue(cl, ub);

out:
	if (free)
		ubus_msg_free(ub);
}
Example #15
0
int main(int argc, char **argv)
{
	const char *ubus_socket = UBUS_UNIX_SOCKET;//定义在cmake中,UBUS_UNIX_SOCKET="/var/run/ubus.sock"
	int ret = 0;
	int ch;

	signal(SIGPIPE, SIG_IGN);//入参:信号类型;处理函数handler。

	uloop_init();

	while ((ch = getopt(argc, argv, "s:")) != -1) {
		switch (ch) {
		case 's':
			ubus_socket = optarg;
			break;
		default:
			return usage(argv[0]);
		}
	}

	unlink(ubus_socket);//unlink,删除/var/run/ubus.sock文件
	umask(0177);//umask,设置用户创建新文件时文件的默认权限。
	server_fd.fd = usock(USOCK_UNIX | USOCK_SERVER | USOCK_NONBLOCK, ubus_socket, NULL);
	if (server_fd.fd < 0) {//usock,首参为套接字类型,ubus_socket可为"127.0.0.1"或var/run/ubus.sock,最后一个为服务端口号"22"或NULL
		perror("usock");
		ret = -1;
		goto out;
	}
	uloop_fd_add(&server_fd, ULOOP_READ | ULOOP_EDGE_TRIGGER);

	uloop_run();//调用uloop_run(),ubusd进程不会再退出--->ubusd通过select方法监听套接字/var/run/ubus.sock,接收ubus发出的服务查询/请求,并将服务请求转发给netifd等提供服务的进程。
	unlink(ubus_socket);

out:
	uloop_done();
	return ret;
}
Example #16
0
static bool get_next_connection(int fd)
{
	struct ubus_client *cl;
	int client_fd;

	client_fd = accept(fd, NULL, 0);
	if (client_fd < 0) {
		switch (errno) {
		case ECONNABORTED:
		case EINTR:
			return true;
		default:
			return false;
		}
	}

	cl = ubusd_proto_new_client(client_fd, client_cb);
	if (cl)
		uloop_fd_add(&cl->sock, ULOOP_READ | ULOOP_EDGE_TRIGGER);
	else
		close(client_fd);

	return true;
}
Example #17
0
int jrpc_server_init(struct jrpc_server *server, char *host, char *port)
{
	char *debug_level_env = getenv("JRPC_DEBUG");

	if (debug_level_env == NULL) {
		server->debug_level = 0;
	} else {
		server->debug_level = strtol(debug_level_env, NULL, 10);
		dlog("JSONRPC-C Debug level %d\n", server->debug_level);
	}

	server->sock.cb = server_cb;
	server->sock.fd =
	    usock(USOCK_TCP | USOCK_SERVER | USOCK_IPV4ONLY | USOCK_NUMERIC,
		  host, port);
	if (server->sock.fd < 0) {
		perror("usock");
		return 1;
	}

	system_fd_set_cloexec(server->sock.fd);
	uloop_fd_add(&server->sock, ULOOP_READ | ULOOP_EDGE_TRIGGER);
	return 0;
}
Example #18
0
static bool get_next_connection(int server_fd, struct jrpc_server *server)
{
	struct jrpc_connection *conn;
	int fd;
	struct sockaddr_in a;
	socklen_t len;

	memset(&a, 0, sizeof(a));
	len = sizeof(struct sockaddr);
	fd = accept(server_fd, (struct sockaddr *)&a, &len);
	if (fd < 0) {
		/*
		   elog("accept[0x%08x] error[%d] error[%d] return false\n", server_fd, fd, errno);
		 */
		switch (errno) {
		case ECONNABORTED:
		case EINTR:
			return true;
		default:

			return false;
		}
	}
	conn = new_connection(fd, connection_cb);
	if (conn) {
		memcpy(&conn->addr, &a, sizeof(a));
		system_fd_set_cloexec(conn->sock.fd);
		conn->server = server;
		conn->debug_level = server->debug_level;
		uloop_fd_add(&conn->sock, ULOOP_READ);
	} else {
		close(fd);
	}

	return true;
}
Example #19
0
int main(int argc, char *argv[])
{
    config_init(argc, argv);

    if (glue_init() != 0)
    {
        iotc_error("glue init failed!");
        return -1;
    }

    if (0 != connection_init())
    {
        iotc_error("socket_init failed!");
        return -1;
    }

    uloop_init();
    uloop_fd_add(&iotc_monitor_uloop_fd, ULOOP_READ);
    uloop_timeout_set(&g_sendDevOnlineTm, 2000);
    uloop_run();
    uloop_done();

    return 0;
}
Example #20
0
int network_init(struct uci_context *uci)
{
  memset(&net_status, 0, sizeof(struct network_status));

  // Initialize the discovered units AVL tree.
  avl_init(&discovered_units, avl_strcmp, false, NULL);

  // Initialize multicast group address.
  inet_pton(AF_INET6, KORUZA_MULTICAST_GROUP, &multicast_group);

  char *interface = uci_get_string(uci, "koruza.@network[0].interface");
  if (!interface) {
    syslog(LOG_WARNING, "Network interface not configured. Skipping network initialization.");
    return 0;
  }

  net_status.interface = strdup(interface);
  free(interface);

  // Discover interface IPv4 address.
  timer_address_update.cb = network_update_local_address;
  network_update_local_address(&timer_address_update);

  // Prepare multicast socket, listen for updates.
  ad_socket.fd = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
  if (ad_socket.fd < 0) {
    syslog(LOG_ERR, "Failed to setup autodiscovery socket.");
    return -1;
  }

  if (setsockopt(ad_socket.fd, SOL_SOCKET, SO_BINDTODEVICE, net_status.interface, strlen(net_status.interface)) != 0) {
    syslog(LOG_ERR, "Failed to bind autodiscovery socket to configured interface.");
    close(ad_socket.fd);
    return -1;
  }

  struct sockaddr_in6 address;
  memset(&address, 0, sizeof(address));
  address.sin6_family = AF_INET6;
  address.sin6_port = htons(10424);
  if (bind(ad_socket.fd, (struct sockaddr*) &address, sizeof(address)) != 0) {
    syslog(LOG_ERR, "Failed to bind autodiscovery socket.");
    close(ad_socket.fd);
    return -1;
  }

  // Subscribe to multicast messages.
  struct ipv6_mreq mreq;
  memcpy(&mreq.ipv6mr_multiaddr, &multicast_group, sizeof(multicast_group));
  mreq.ipv6mr_interface = 0;

  if (setsockopt(ad_socket.fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) != 0) {
    syslog(LOG_ERR, "Failed to join multicast group.");
    close(ad_socket.fd);
    return -1;
  }

  // Set hop limit for sent multicast messages.
  int hops = 1;
  if (setsockopt(ad_socket.fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, sizeof(hops)) != 0) {
    syslog(LOG_ERR, "Failed to configure hop limit.");
    close(ad_socket.fd);
    return -1;
  }

  // Add socket to uloop.
  ad_socket.cb = network_message_received;
  uloop_fd_add(&ad_socket, ULOOP_READ);

  // Setup announce timer.
  timer_announce.cb = network_announce_ourselves;
  uloop_timeout_set(&timer_announce, KORUZA_ANNOUNCE_INTERVAL);

  syslog(LOG_INFO, "Initialized network on interface %s (%s).", net_status.interface, net_status.ip_address);
  net_status.ready = 1;

  // Setup any staticly configured peers.
  char *peer_ip = uci_get_string(uci, "koruza.@network[0].peer");
  if (peer_ip) {
    struct network_device device;
    device.version = 0;
    device.id = "STATIC";
    device.ip_address = peer_ip;
    if (network_add_device(&device) != 0) {
      syslog(LOG_WARNING, "Unable to add static network peer.");
    }
    free(peer_ip);
  }

  return 0;
}
Example #21
0
static int ubus_msg_writev(int fd, struct ubus_msg_buf *ub, int offset)
{
	static struct iovec iov[2];
	static struct {
		struct cmsghdr h;
		int fd;
	} fd_buf = {
		.h = {
			.cmsg_len = sizeof(fd_buf),
			.cmsg_level = SOL_SOCKET,
			.cmsg_type = SCM_RIGHTS,
		},
	};
	struct msghdr msghdr = {
		.msg_iov = iov,
		.msg_iovlen = ARRAY_SIZE(iov),
		.msg_control = &fd_buf,
		.msg_controllen = sizeof(fd_buf),
	};

	fd_buf.fd = ub->fd;
	if (ub->fd < 0) {
		msghdr.msg_control = NULL;
		msghdr.msg_controllen = 0;
	}

	if (offset < sizeof(ub->hdr)) {
		iov[0].iov_base = ((char *) &ub->hdr) + offset;
		iov[0].iov_len = sizeof(ub->hdr) - offset;
		iov[1].iov_base = (char *) ub->data;
		iov[1].iov_len = ub->len;

		return sendmsg(fd, &msghdr, 0);
	} else {
		offset -= sizeof(ub->hdr);
		return write(fd, ((char *) ub->data) + offset, ub->len - offset);
	}
}

static void ubus_msg_enqueue(struct ubus_client *cl, struct ubus_msg_buf *ub)
{
	if (cl->tx_queue[cl->txq_tail])
		return;

	cl->tx_queue[cl->txq_tail] = ubus_msg_ref(ub);
	cl->txq_tail = (cl->txq_tail + 1) % ARRAY_SIZE(cl->tx_queue);
}

/* takes the msgbuf reference */
void ubus_msg_send(struct ubus_client *cl, struct ubus_msg_buf *ub, bool free)
{
	int written;

	if (!cl->tx_queue[cl->txq_cur]) {
		written = ubus_msg_writev(cl->sock.fd, ub, 0);
		if (written >= ub->len + sizeof(ub->hdr))
			goto out;

		if (written < 0)
			written = 0;

		cl->txq_ofs = written;

		/* get an event once we can write to the socket again */
		uloop_fd_add(&cl->sock, ULOOP_READ | ULOOP_WRITE | ULOOP_EDGE_TRIGGER);
	}
	ubus_msg_enqueue(cl, ub);

out:
	if (free)
		ubus_msg_free(ub);
}
Example #22
0
static void client_cb(struct uloop_fd *sock, unsigned int events)
{
	struct ubus_client *cl = container_of(sock, struct ubus_client, sock);
	struct ubus_msg_buf *ub;
	static struct iovec iov;
	static struct {
		struct cmsghdr h;
		int fd;
	} fd_buf = {
		.h = {
			.cmsg_type = SCM_RIGHTS,
			.cmsg_level = SOL_SOCKET,
			.cmsg_len = sizeof(fd_buf),
		}
	};
	struct msghdr msghdr = {
		.msg_iov = &iov,
		.msg_iovlen = 1,
	};

	/* first try to tx more pending data */
	while ((ub = ubus_msg_head(cl))) {
		int written;

		written = ubus_msg_writev(sock->fd, ub, cl->txq_ofs);
		if (written < 0) {
			switch(errno) {
			case EINTR:
			case EAGAIN:
				break;
			default:
				goto disconnect;
			}
			break;
		}

		cl->txq_ofs += written;
		if (cl->txq_ofs < ub->len + sizeof(ub->hdr))
			break;

		ubus_msg_dequeue(cl);
	}

	/* prevent further ULOOP_WRITE events if we don't have data
	 * to send anymore */
	if (!ubus_msg_head(cl) && (events & ULOOP_WRITE))
		uloop_fd_add(sock, ULOOP_READ | ULOOP_EDGE_TRIGGER);

retry:
	if (!sock->eof && cl->pending_msg_offset < sizeof(cl->hdrbuf)) {
		int offset = cl->pending_msg_offset;
		int bytes;

		fd_buf.fd = -1;

		iov.iov_base = ((char *) &cl->hdrbuf) + offset;
		iov.iov_len = sizeof(cl->hdrbuf) - offset;

		if (cl->pending_msg_fd < 0) {
			msghdr.msg_control = &fd_buf;
			msghdr.msg_controllen = sizeof(fd_buf);
		} else {
			msghdr.msg_control = NULL;
			msghdr.msg_controllen = 0;
		}

		bytes = recvmsg(sock->fd, &msghdr, 0);
		if (bytes < 0)
			goto out;

		if (fd_buf.fd >= 0)
			cl->pending_msg_fd = fd_buf.fd;

		cl->pending_msg_offset += bytes;
		if (cl->pending_msg_offset < sizeof(cl->hdrbuf))
			goto out;

		if (blob_pad_len(&cl->hdrbuf.data) > UBUS_MAX_MSGLEN)
			goto disconnect;

		cl->pending_msg = ubus_msg_new(NULL, blob_raw_len(&cl->hdrbuf.data), false);
		if (!cl->pending_msg)
			goto disconnect;

		memcpy(&cl->pending_msg->hdr, &cl->hdrbuf.hdr, sizeof(cl->hdrbuf.hdr));
		memcpy(cl->pending_msg->data, &cl->hdrbuf.data, sizeof(cl->hdrbuf.data));
	}

	ub = cl->pending_msg;
	if (ub) {
		int offset = cl->pending_msg_offset - sizeof(ub->hdr);
		int len = blob_raw_len(ub->data) - offset;
		int bytes = 0;

		if (len > 0) {
			bytes = read(sock->fd, (char *) ub->data + offset, len);
			if (bytes <= 0)
				goto out;
		}

		if (bytes < len) {
			cl->pending_msg_offset += bytes;
			goto out;
		}

		/* accept message */
		ub->fd = cl->pending_msg_fd;
		cl->pending_msg_fd = -1;
		cl->pending_msg_offset = 0;
		cl->pending_msg = NULL;
		ubusd_proto_receive_message(cl, ub);
		goto retry;
	}

out:
	if (!sock->eof || ubus_msg_head(cl))
		return;

disconnect:
	handle_client_disconnect(cl);
}

static bool get_next_connection(int fd)
{
	struct ubus_client *cl;
	int client_fd;

	client_fd = accept(fd, NULL, 0);
	if (client_fd < 0) {
		switch (errno) {
		case ECONNABORTED:
		case EINTR:
			return true;
		default:
			return false;
		}
	}

	cl = ubusd_proto_new_client(client_fd, client_cb);
	if (cl)
		uloop_fd_add(&cl->sock, ULOOP_READ | ULOOP_EDGE_TRIGGER);
	else
		close(client_fd);

	return true;
}

static void server_cb(struct uloop_fd *fd, unsigned int events)
{
	bool next;

	do {
		next = get_next_connection(fd->fd);
	} while (next);
}
Example #23
0
int main(int argc, char **argv)
{
	int opt, rc = 0;

	while ((opt = getopt(argc, argv, "hv")) != -1) {
		switch (opt) {
		case 'v':
			conf.verbosity++;
			break;
		case 'h':
		default:
			return usage(argv[0]);
		}	
	}

	conf.flx_ufd.fd = open(FLX_DEV, O_RDWR);
	if (conf.flx_ufd.fd < 0) {
		perror(FLX_DEV);
		rc = 1;
		goto finish;
	}
	if (!configure_tty(conf.flx_ufd.fd)) {
		fprintf(stderr, "%s: Failed to configure tty params\n", FLX_DEV);
		rc = 2;
		goto finish;
	}

	if (!config_init()) {
		rc = 3;
		goto oom;
	}
	if (!config_load_all()) {
		rc = 4;
		goto finish;
	}

	conf.ubus_ctx = ubus_connect(NULL);
	if (!conf.ubus_ctx) {
		fprintf(stderr, "Failed to connect to ubus\n");
		rc = 5;
		goto finish;
	}

#ifdef WITH_YKW
	conf.ykw = ykw_new(YKW_DEFAULT_THETA);
	if (conf.ykw == NULL) {
		rc = 6;
		goto oom;
	}
#endif

	mosquitto_lib_init();
	snprintf(conf.mqtt.id, MQTT_ID_LEN, MQTT_ID_TPL, getpid());
	conf.mosq = mosquitto_new(conf.mqtt.id, conf.mqtt.clean_session, &conf);
	if (!conf.mosq) {
		switch (errno) {
		case ENOMEM:
			rc = 7;
			goto oom;
		case EINVAL:
			fprintf(stderr, "mosq_new: Invalid id and/or clean_session.\n");
			rc = 8;
			goto finish;
		}
	}
	rc = mosquitto_loop_start(conf.mosq);
	switch (rc) {
	case MOSQ_ERR_INVAL:
		fprintf(stderr, "mosq_loop_start: Invalid input parameters.\n");
		goto finish;
	case MOSQ_ERR_NOT_SUPPORTED:
		fprintf(stderr, "mosq_loop_start: No threading support.\n");
		goto finish;
	};
	rc = mosquitto_connect_async(conf.mosq, conf.mqtt.host, conf.mqtt.port,
	                  conf.mqtt.keepalive);
	switch (rc) {
	case MOSQ_ERR_INVAL:
		fprintf(stderr, "mosq_connect_async: Invalid input parameters.\n");
		goto finish;
	case MOSQ_ERR_ERRNO:
		perror("mosq_connect_async");
		goto finish;
	}

	uloop_init();
	uloop_fd_add(&conf.flx_ufd, ULOOP_READ);
	uloop_timeout_set(&conf.timeout, CONFIG_ULOOP_TIMEOUT);
	ubus_add_uloop(conf.ubus_ctx);
	ubus_register_event_handler(conf.ubus_ctx, &conf.ubus_ev_sighup,
	                            CONFIG_UBUS_EV_SIGHUP);
	ubus_register_event_handler(conf.ubus_ctx, &conf.ubus_ev_shift_calc,
	                            CONFIG_UBUS_EV_SHIFT_CALC);
	uloop_run();
	uloop_done();
	goto finish;

oom:
	fprintf(stderr, "error: Out of memory.\n");
finish:
	mosquitto_disconnect(conf.mosq);
	mosquitto_loop_stop(conf.mosq, false);
	mosquitto_destroy(conf.mosq);
	mosquitto_lib_cleanup();
	ykw_free(conf.ykw);
	if (conf.ubus_ctx != NULL) {
		ubus_free(conf.ubus_ctx);
	}
	close(conf.flx_ufd.fd);
	uci_free_context(conf.uci_ctx);
	return rc;
}
Example #24
0
static void client_cb(struct uloop_fd *sock, unsigned int events)
{
	struct ubus_client *cl = container_of(sock, struct ubus_client, sock);
	struct ubus_msg_buf *ub;

	/* first try to tx more pending data */
	while ((ub = ubus_msg_head(cl))) {
		int written;

		written = ubus_msg_writev(sock->fd, ub, cl->txq_ofs);
		if (written < 0) {
			switch(errno) {
			case EINTR:
			case EAGAIN:
				break;
			default:
				goto disconnect;
			}
			break;
		}

		cl->txq_ofs += written;
		if (cl->txq_ofs < ub->len + sizeof(ub->hdr))
			break;

		ubus_msg_dequeue(cl);
	}

	/* prevent further ULOOP_WRITE events if we don't have data
	 * to send anymore */
	if (!ubus_msg_head(cl) && (events & ULOOP_WRITE))
		uloop_fd_add(sock, ULOOP_READ | ULOOP_EDGE_TRIGGER);

retry:
	if (!sock->eof && cl->pending_msg_offset < sizeof(cl->hdrbuf)) {
		int offset = cl->pending_msg_offset;
		int bytes;

		bytes = read(sock->fd, (char *)&cl->hdrbuf + offset, sizeof(cl->hdrbuf) - offset);
		if (bytes < 0)
			goto out;

		cl->pending_msg_offset += bytes;
		if (cl->pending_msg_offset < sizeof(cl->hdrbuf))
			goto out;

		if (blob_pad_len(&cl->hdrbuf.data) > UBUS_MAX_MSGLEN)
			goto disconnect;

		cl->pending_msg = ubus_msg_new(NULL, blob_raw_len(&cl->hdrbuf.data), false);
		if (!cl->pending_msg)
			goto disconnect;

		memcpy(&cl->pending_msg->hdr, &cl->hdrbuf.hdr, sizeof(cl->hdrbuf.hdr));
		memcpy(cl->pending_msg->data, &cl->hdrbuf.data, sizeof(cl->hdrbuf.data));
	}

	ub = cl->pending_msg;
	if (ub) {
		int offset = cl->pending_msg_offset - sizeof(ub->hdr);
		int len = blob_raw_len(ub->data) - offset;
		int bytes = 0;

		if (len > 0) {
			bytes = read(sock->fd, (char *) ub->data + offset, len);
			if (bytes <= 0)
				goto out;
		}

		if (bytes < len) {
			cl->pending_msg_offset += bytes;
			goto out;
		}

		/* accept message */
		cl->pending_msg_offset = 0;
		cl->pending_msg = NULL;
		ubusd_proto_receive_message(cl, ub);
		goto retry;
	}

out:
	if (!sock->eof || ubus_msg_head(cl))
		return;

disconnect:
	handle_client_disconnect(cl);
}
Example #25
0
File: rrdns.c Project: jow-/luci-ng
static int
rpc_rrdns_lookup(struct ubus_context *ctx, struct ubus_object *obj,
                 struct ubus_request_data *req, const char *method,
                 struct blob_attr *msg)
{
    int port = 53, limit = RRDNS_DEF_LIMIT, timeout = RRDNS_DEF_TIMEOUT;
    struct blob_attr *tb[__RPC_L_MAX];
    struct rrdns_context *rctx;
    const char *server = NULL;

    blobmsg_parse(rpc_lookup_policy, __RPC_L_MAX, tb,
                  blob_data(msg), blob_len(msg));

    if (tb[RPC_L_PORT])
        port = blobmsg_get_u16(tb[RPC_L_PORT]);

    if (tb[RPC_L_LIMIT])
        limit = blobmsg_get_u32(tb[RPC_L_LIMIT]);

    if (tb[RPC_L_TIMEOUT])
        timeout = blobmsg_get_u32(tb[RPC_L_TIMEOUT]);

    if (tb[RPC_L_SERVER])
        server = blobmsg_get_string(tb[RPC_L_SERVER]);


    if (!tb[RPC_L_ADDRS])
        return UBUS_STATUS_INVALID_ARGUMENT;

    if (port <= 0)
        return UBUS_STATUS_INVALID_ARGUMENT;

    if (limit <= 0 || limit > RRDNS_MAX_LIMIT)
        return UBUS_STATUS_INVALID_ARGUMENT;

    if (timeout <= 0 || timeout > RRDNS_MAX_TIMEOUT)
        return UBUS_STATUS_INVALID_ARGUMENT;


    if (!server || !*server)
        server = rrdns_find_nameserver();

    if (!server)
        return UBUS_STATUS_NOT_FOUND;

    rctx = calloc(1, sizeof(*rctx));

    if (!rctx)
        return UBUS_STATUS_UNKNOWN_ERROR;

    rctx->socket.fd = usock(USOCK_UDP, server, usock_port(port));

    if (rctx->socket.fd < 0) {
        free(rctx);
        return UBUS_STATUS_UNKNOWN_ERROR;
    }

    rctx->context = ctx;
    rctx->addr_cur = blobmsg_data(tb[RPC_L_ADDRS]);
    rctx->addr_rem = blobmsg_data_len(tb[RPC_L_ADDRS]);

    avl_init(&rctx->request_ids, rrdns_cmp_id, false, NULL);
    avl_init(&rctx->request_addrs, rrdns_cmp_addr, false, NULL);

    rctx->timeout.cb = rrdns_handle_timeout;
    uloop_timeout_set(&rctx->timeout, timeout);

    rctx->socket.cb = rrdns_handle_response;
    uloop_fd_add(&rctx->socket, ULOOP_READ);

    blob_buf_init(&rctx->blob, 0);

    while (limit--)
        rrdns_next_query(rctx);

    ubus_defer_request(ctx, req, &rctx->request);

    return UBUS_STATUS_OK;
}