/* * moved here from vhci_attach.c */ int tcp_connect(char *hostname, char *service) { struct addrinfo hints, *res, *res0; int sockfd; int err; memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; /* get all possible addresses */ err = getaddrinfo(hostname, service, &hints, &res0); if (err) { err("%s %s: %s", hostname, service, gai_strerror(err)); return -1; } /* try all the addresses */ for (res = res0; res; res = res->ai_next) { char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; err = getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV); if (err) { err("%s %s: %s", hostname, service, gai_strerror(err)); continue; } dbg("trying %s port %s\n", hbuf, sbuf); sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (sockfd < 0) { err("socket"); continue; } /* should set TCP_NODELAY for usbip */ usbip_set_nodelay(sockfd); /* TODO: write code for heatbeat */ usbip_set_keepalive(sockfd); err = connect(sockfd, res->ai_addr, res->ai_addrlen); if (err < 0) { close(sockfd); continue; } /* connected */ dbg("connected to %s:%s", hbuf, sbuf); freeaddrinfo(res0); return sockfd; } dbg("%s:%s, %s", hostname, service, "no destination to connect to"); freeaddrinfo(res0); return -1; }
static int listen_all_addrinfo(struct addrinfo *ai_head, int lsock[]) { struct addrinfo *ai; int n = 0; /* number of sockets */ for (ai = ai_head; ai && n < MAXSOCK; ai = ai->ai_next) { int ret; lsock[n] = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (lsock[n] < 0) continue; usbip_set_reuseaddr(lsock[n]); usbip_set_nodelay(lsock[n]); if (lsock[n] >= FD_SETSIZE) { close(lsock[n]); lsock[n] = -1; continue; } ret = bind(lsock[n], ai->ai_addr, ai->ai_addrlen); if (ret < 0) { close(lsock[n]); lsock[n] = -1; continue; } ret = listen(lsock[n], SOMAXCONN); if (ret < 0) { close(lsock[n]); lsock[n] = -1; continue; } log_addrinfo(ai); /* next if succeed */ n++; } if (n == 0) { err("no socket to listen to"); return -1; } dbg("listen %d address%s", n, (n==1)?"":"es"); return n; }
static int recv_request_import(int sockfd) { int ret; struct op_import_request req; struct op_common reply; struct usbip_exported_device *edev; int found = 0; int error = 0; bzero(&req, sizeof(req)); bzero(&reply, sizeof(reply)); ret = usbip_recv(sockfd, (void *) &req, sizeof(req)); if (ret < 0) { err("recv import request"); return -1; } PACK_OP_IMPORT_REQUEST(0, &req); dlist_for_each_data(stub_driver->edev_list, edev, struct usbip_exported_device) { if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) { dbg("found requested device %s", req.busid); found = 1; break; } } if (found) { /* should set TCP_NODELAY for usbip */ usbip_set_nodelay(sockfd); /* export_device needs a TCP/IP socket descriptor */ ret = usbip_stub_export_device(edev, sockfd); if (ret < 0) error = 1; } else { info("not found requested device %s", req.busid); error = 1; } ret = usbip_send_op_common(sockfd, OP_REP_IMPORT, (!error ? ST_OK : ST_NA)); if (ret < 0) { err("send import reply"); return -1; } if (!error) { struct usb_device pdu_udev; memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev)); pack_usb_device(1, &pdu_udev); ret = usbip_send(sockfd, (void *) &pdu_udev, sizeof(pdu_udev)); if (ret < 0) { err("send devinfo"); return -1; } } return 0; }