Ejemplo n.º 1
0
struct channel *
s_create_data_channel(void) {
    uint64_t dpid = 0x01;
    struct channel *channel;
    lagopus_session_t session;
    struct addrunion addr  = {0,{{0}}};

    addrunion_ipv4_set(&addr, "127.0.0.1");
    channel = channel_alloc(&addr, dpid);

    (void) session_create(SESSION_TCP|SESSION_ACTIVE, &session);
    session_write_set(session, write_tcp);

    channel_version_set(channel, 0x04);
    channel_session_set(channel, session);
    channel_xid_set(channel, 0x10);

    return channel;
}
Ejemplo n.º 2
0
static lagopus_result_t
channel_add_internal(const char *channel_name, struct addrunion *addr,
                     struct channel **channel) {
  lagopus_result_t ret;
  struct channel *chan = NULL;
  void *valptr = NULL;

  if (main_table == NULL) {
    return LAGOPUS_RESULT_ANY_FAILURES;
  }

  ret = lagopus_hashmap_find(&main_table, (void *)channel_name, (void **)&chan);
  if (ret == LAGOPUS_RESULT_OK && chan != NULL) {
    /* FIXME support auxiliary connections */
    return LAGOPUS_RESULT_ALREADY_EXISTS;
  } else if (ret != LAGOPUS_RESULT_NOT_FOUND) {
    return ret;
  }

#define UNUSED_DPID 0
  chan = channel_alloc(addr, em, UNUSED_DPID);
  if (chan == NULL) {
    return LAGOPUS_RESULT_NO_MEMORY;
  }

  lagopus_msg_debug(10, "channel allocated  %p\n", chan);

  valptr = chan;
  ret = lagopus_hashmap_add(&main_table, (void *)channel_name, (void **)&valptr,
                            false);
  if (ret != LAGOPUS_RESULT_OK) {
    channel_free(chan);
  }

  if (ret != LAGOPUS_RESULT_OK) {
    channel_delete_internal((const char *) channel_name);
  } else {
    *channel = chan;
  }

  return ret;
}
Ejemplo n.º 3
0
void
tap_init(void)
{
	channel_t *chan;
	struct ifreq ifr;
	int fd, s;
	char pidfile[PATH_MAX];

	fd = open(interface_name, O_RDWR);
	if (fd == -1) {
		log_err("Could not open \"%s\": %m", interface_name);
		exit(EXIT_FAILURE);
	}

	memset(&ifr, 0, sizeof(ifr));
	if (ioctl(fd, TAPGIFNAME, &ifr) == -1) {
		log_err("Could not get interface name: %m");
		exit(EXIT_FAILURE);
	}

	s = socket(AF_INET, SOCK_DGRAM, 0);
	if (s == -1) {
		log_err("Could not open PF_LINK socket: %m");
		exit(EXIT_FAILURE);
	}

	ifr.ifr_addr.sa_family = AF_LINK;
	ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
	b2eaddr(ifr.ifr_addr.sa_data, &local_bdaddr);

	if (ioctl(s, SIOCSIFLLADDR, &ifr) == -1) {
		log_err("Could not set %s physical address: %m", ifr.ifr_name);
		exit(EXIT_FAILURE);
	}

	if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
		log_err("Could not get interface flags: %m");
		exit(EXIT_FAILURE);
	}

	if ((ifr.ifr_flags & IFF_UP) == 0) {
		ifr.ifr_flags |= IFF_UP;

		if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
			log_err("Could not set IFF_UP: %m");
			exit(EXIT_FAILURE);
		}
	}

	close(s);

	log_info("Using interface %s with addr %s", ifr.ifr_name,
		ether_ntoa((struct ether_addr *)&ifr.ifr_addr.sa_data));

	chan = channel_alloc();
	if (chan == NULL)
		exit(EXIT_FAILURE);

	chan->send = tap_send;
	chan->recv = tap_recv;
	chan->mru = ETHER_HDR_LEN + ETHER_MAX_LEN;
	memcpy(chan->raddr, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN);
	memcpy(chan->laddr, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN);
	chan->state = CHANNEL_OPEN;
	if (!channel_open(chan, fd))
		exit(EXIT_FAILURE);

	snprintf(pidfile, sizeof(pidfile), "%s/%s.pid",
		_PATH_VARRUN, ifr.ifr_name);
	chan->pfh = pidfile_open(pidfile, 0600, NULL);
	if (chan->pfh == NULL)
		log_err("can't create pidfile");
	else if (pidfile_write(chan->pfh) < 0) {
		log_err("can't write pidfile");
		pidfile_remove(chan->pfh);
		chan->pfh = NULL;
	}
}
Ejemplo n.º 4
0
FILE *profile_fopen(const char *fname, const char *mode)
{
  char *key = NULL, *val = NULL, *rsp = NULL, *domStr = NULL, *diskname = NULL;
  uint32_t req, rsptype, rsplen, domId;
  XenStorePaths *xsp = NULL;
  uint64_t store_mptr;
  FILE *retval = NULL;
  int vallen;
  long res;

  if(strncmp(mode, "w", 1) != 0)
    goto fail;

  if(strncmp(fname, "HaLVM.prof", 11) == 0)
    diskname = "xvdp1";
  if(strncmp(fname, "HaLVM.hp", 9) == 0)
    diskname = "xvdp2";
  if(!diskname)
    goto fail;

  store_mptr = (uint64_t)system_start_info->store_mfn << 12;
  unmask_channel(system_start_info->store_evtchn);
  xsint = (struct xenstore_domain_interface*)machine_to_virtual(store_mptr);
  if(!xsint) {
    printf("PROFILING ERROR: Could not map XenStore page.\n");
    goto fail;
  }

  /* Try to run "ls devices/vbd" */
  req = xenstore_write(XS_DIRECTORY, strlen("device/vbd") + 1, "device/vbd");
  rsplen = xenstore_read(req, &rsptype, (void**)&rsp);
  if(rsptype == XS_ERROR) {
    printf("PROFILING: XenStore read error. Did you forget to add a disk?\n");
    goto fail;
  }
  if(rsptype != XS_DIRECTORY) {
    printf("PROFILING: XenStore has gone weird. Giving up.\n");
    goto fail;
  }

  /* Find the XenStore paths associated with the disk we want */
  xsp = find_xs_paths(diskname, rsp, rsplen);
  if(!xsp) {
    printf("PROFILING: Couldn't find file to open.\n");
    goto fail;
  }

  /* Pull out the other's domId */
  key = malloc(256);
  snprintf(key, 256, "%s/backend-id", xsp->feDir);
  domStr = xenstore_getkey(key);
  domId = atoi(domStr);

  /* allocate the return structure and buffers */
  retval = malloc(sizeof(FILE));
  if(!retval)
    goto fail;
  memset(retval, 0, sizeof(FILE));
  retval->cur_block_num = 1;
  retval->block = runtime_alloc(NULL, 4096, PROT_READ|PROT_WRITE);
  if(!retval->block)
    goto fail;
  assert( (((uintptr_t)retval->block) & 4095) == 0 );
  retval->ring.sring = runtime_alloc(NULL, 4096, PROT_READ|PROT_WRITE);
  if(!retval->ring.sring)
    goto fail;
  assert( (((uintptr_t)retval->ring.sring) & 4095) == 0 );
  SHARED_RING_INIT(retval->ring.sring);
  FRONT_RING_INIT(&(retval->ring), retval->ring.sring, 4096);

  /* get the device handle */
  snprintf(key, 256, "%s/virtual-device", xsp->feDir);
  val = xenstore_getkey(key);
  retval->disk_handle = atoi(val);

  /* allocate the grant references and event channel */
  res = alloc_grant(domId, retval->ring.sring, 4096, 0, &retval->ring_grant);
  if(res) {
    printf("PROFILING: Failed to allocate ring grant reference: %d\n", res);
    goto fail;
  }
  res = alloc_grant(domId, retval->block, 4096, 0, &retval->block_grant);
  if(res) {
    printf("PROFILING: Failed to allocate block grant reference: %d\n", res);
    goto fail;
  }
  res = channel_alloc(DOMID_SELF, domId);
  if(res < 0) {
    printf("PROFILING: Failed to allocate grant reference: %d\n", res);
    goto fail;
  }
  retval->chan = (uint32_t)res;
  set_c_handler(retval->chan, handler);

  /* write them into our tree */
  val    = malloc(256);
  /*    */ snprintf(key, 256, "%s/ring-ref", xsp->feDir);
  vallen = snprintf(val, 256, "%d", retval->ring_grant);
  if(!xenstore_setkey(key, val, vallen)) goto fail;
  /*    */ snprintf(key, 256, "%s/event-channel", xsp->feDir);
  vallen = snprintf(val, 256, "%d", retval->chan);
  if(!xenstore_setkey(key, val, vallen)) goto fail;
  /*    */ snprintf(key, 256, "%s/state", xsp->feDir);
  vallen = snprintf(val, 256, "%d", XenbusStateInitialised);
  if(!xenstore_setkey(key, val, vallen)) goto fail;

  /* wait for the other side to sync up */
  do {
    char *state;

    runtime_block(1);
    snprintf(key, 256, "%s/state", xsp->beDir);
    state = xenstore_getkey(key);
    res = atoi(state);
    free(state);
  } while(res != XenbusStateConnected);

  /* write out that we're good */
  /*    */ snprintf(key, 256, "%s/state", xsp->feDir);
  vallen = snprintf(val, 256, "%d", XenbusStateConnected);
  if(!xenstore_setkey(key, val, vallen)) goto fail;

  return retval;

fail:
  if(key) free(key);
  if(val) free(val);
  if(rsp) free(rsp);
  if(xsp) {
    free(xsp->feDir);
    free(xsp->beDir);
    free(xsp);
  }
  if(domStr) free(domStr);
  if(retval) {
    if(retval->block_grant) end_grant(retval->block_grant);
    if(retval->ring_grant) end_grant(retval->ring_grant);
    if(retval->block) runtime_free(retval->block, 4096);
    if(retval->ring.sring) runtime_free(retval->ring.sring, 4096);
    if(retval->chan) channel_close(retval->chan);
    free(retval);
  }
  errno = -EACCES;
  return NULL;
}
Ejemplo n.º 5
0
void
client_init(void)
{
	struct sockaddr_l2cap sa;
	channel_t *chan;
	socklen_t len;
	int fd, n;
	uint16_t mru, mtu;

	if (bdaddr_any(&remote_bdaddr))
		return;

	if (service_name)
		client_query();

	fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BLUETOOTH_PROTO_L2CAP);
	if (fd == -1) {
		log_err("Could not open L2CAP socket: %m");
		exit(EXIT_FAILURE);
	}

	memset(&sa, 0, sizeof(sa));
	sa.l2cap_family = AF_BLUETOOTH;
	sa.l2cap_len = sizeof(sa);
	sa.l2cap_bdaddr_type = BDADDR_BREDR;
	sa.l2cap_cid = 0;
	 
	bdaddr_copy(&sa.l2cap_bdaddr, &local_bdaddr);
	if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
		log_err("Could not bind client socket: %m");
		exit(EXIT_FAILURE);
	}

	mru = BNEP_MTU_MIN;
	if (setsockopt(fd, SOL_L2CAP, SO_L2CAP_IMTU, &mru, sizeof(mru)) == -1) {
		log_err("Could not set L2CAP IMTU (%d): %m", mru);
		exit(EXIT_FAILURE);
	}

	log_info("Opening connection to service 0x%4.4x at %s",
	    service_class, bt_ntoa(&remote_bdaddr, NULL));

	sa.l2cap_psm = htole16(l2cap_psm);
	bdaddr_copy(&sa.l2cap_bdaddr, &remote_bdaddr);
	if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
		log_err("Could not connect: %m");
		exit(EXIT_FAILURE);
	}

	len = sizeof(mru);
	if (getsockopt(fd, SOL_L2CAP, SO_L2CAP_IMTU, &mru, &len) == -1) {
		log_err("Could not get IMTU: %m");
		exit(EXIT_FAILURE);
	}
	if (mru < BNEP_MTU_MIN) {
		log_err("L2CAP IMTU too small (%d)", mru);
		exit(EXIT_FAILURE);
	}

	len = sizeof(n);
	if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &n, &len) == -1) {
		log_err("Could not read SO_RCVBUF");
		exit(EXIT_FAILURE);
	}
	if (n < (mru * 10)) {
		n = mru * 10;
		if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) == -1)
			log_info("Could not increase SO_RCVBUF (from %d)", n);
	}

	len = sizeof(mtu);
	if (getsockopt(fd, SOL_L2CAP, SO_L2CAP_OMTU, &mtu, &len) == -1) {
		log_err("Could not get L2CAP OMTU: %m");
		exit(EXIT_FAILURE);
	}
	if (mtu < BNEP_MTU_MIN) {
		log_err("L2CAP OMTU too small (%d)", mtu);
		exit(EXIT_FAILURE);
	}

	len = sizeof(n);
	if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &n, &len) == -1) {
		log_err("Could not get socket send buffer size: %m");
		close(fd);
		return;
	}
	if (n < (mtu * 2)) {
		n = mtu * 2;
		if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n)) == -1) {
			log_err("Could not set socket send buffer size (%d): %m", n);
			close(fd);
			return;
		}
	}
	n = mtu;
	if (setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &n, sizeof(n)) == -1) {
		log_err("Could not set socket low water mark (%d): %m", n);
		close(fd);
		return;
	}

	chan = channel_alloc();
	if (chan == NULL)
		exit(EXIT_FAILURE);

	chan->send = bnep_send;
	chan->recv = bnep_recv;
	chan->mru = mru;
	chan->mtu = mtu;
	b2eaddr(chan->raddr, &remote_bdaddr);
	b2eaddr(chan->laddr, &local_bdaddr);
	chan->state = CHANNEL_WAIT_CONNECT_RSP;
	channel_timeout(chan, 10);
	if (!channel_open(chan, fd))
		exit(EXIT_FAILURE);

	bnep_send_control(chan, BNEP_SETUP_CONNECTION_REQUEST,
	    2, service_class, SDP_SERVICE_CLASS_PANU);
}
Ejemplo n.º 6
0
/*
 * handle connection request
 */
static void
server_read(int s, short ev, void *arg)
{
	struct sockaddr_l2cap ra, la;
	channel_t *chan;
	socklen_t len;
	int fd, n;
	uint16_t mru, mtu;

	len = sizeof(ra);
	fd = accept(s, (struct sockaddr *)&ra, &len);
	if (fd == -1)
		return;

	n = 1;
	if (ioctl(fd, FIONBIO, &n) == -1) {
		log_err("Could not set NonBlocking IO: %m");
		close(fd);
		return;
	}

	len = sizeof(mru);
	if (getsockopt(fd, SOL_L2CAP, SO_L2CAP_IMTU, &mru, &len) == -1) {
		log_err("Could not get L2CAP IMTU: %m");
		close(fd);
		return;
	}
	if(mru < BNEP_MTU_MIN) {
		log_err("L2CAP IMTU too small (%d)", mru);
		close(fd);
		return;
	}

	len = sizeof(n);
	if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &n, &len) == -1) {
		log_err("Could not read SO_RCVBUF");
		close(fd);
		return;
	}
	if (n < (mru * 10)) {
		n = mru * 10;
		if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) == -1)
			log_info("Could not increase SO_RCVBUF (from %d)", n);
	}

	len = sizeof(mtu);
	if (getsockopt(fd, SOL_L2CAP, SO_L2CAP_OMTU, &mtu, &len) == -1) {
		log_err("Could not get L2CAP OMTU: %m");
		close(fd);
		return;
	}
	if (mtu < BNEP_MTU_MIN) {
		log_err("L2CAP OMTU too small (%d)", mtu);
		close(fd);
		return;
	}

	len = sizeof(n);
	if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &n, &len) == -1) {
		log_err("Could not get socket send buffer size: %m");
		close(fd);
		return;
	}

	if (n < (mtu * 2)) {
		n = mtu * 2;
		if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n)) == -1) {
			log_err("Could not set socket send buffer size (%d): %m", n);
			close(fd);
			return;
		}
	}

	n = mtu;
	if (setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &n, sizeof(n)) == -1) {
		log_err("Could not set socket low water mark (%d): %m", n);
		close(fd);
		return;
	}

	len = sizeof(la);
	if (getsockname(fd, (struct sockaddr *)&la, &len) == -1) {
		log_err("Could not get socket address: %m");
		close(fd);
		return;
	}

	log_info("Accepted connection from %s", bt_ntoa(&ra.l2cap_bdaddr, NULL));

	chan = channel_alloc();
	if (chan == NULL) {
		close(fd);
		return;
	}

	chan->send = bnep_send;
	chan->recv = bnep_recv;
	chan->mru = mru;
	chan->mtu = mtu;
	b2eaddr(chan->raddr, &ra.l2cap_bdaddr);
	b2eaddr(chan->laddr, &la.l2cap_bdaddr);
	chan->state = CHANNEL_WAIT_CONNECT_REQ;
	channel_timeout(chan, 10);
	if (!channel_open(chan, fd)) {
		chan->state = CHANNEL_CLOSED;
		channel_free(chan);
		close(fd);
		return;
	}
}