Lines Matching +full:auto +full:- +full:retry

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
78 #define HVSOCK_SEND_BUF_SZ (PAGE_SIZE - sizeof(struct vmpipe_proto_header))
122 /* 00000000-facb-11e6-bd58-64006a7986d3 */
150 "0x%x-0x%x-0x%x-0x%x-0x%x-0x%x-0x%x-0x%x-0x%x-0x%x-0x%x\n", in hvsock_print_guid()
160 return !memcmp(&id->hv_guid[4], in is_valid_srv_id()
161 &srv_id_template.hv_guid[4], sizeof(struct hyperv_guid) - 4); in is_valid_srv_id()
227 if (!so || !so->so_pcb) { in hvs_remove_socket_from_list()
241 if (!so || !so->so_pcb) { in hvs_insert_socket_on_list()
259 if (p->so != NULL && in __hvs_find_socket_on_list()
260 addr->hvs_port == p->local_addr.hvs_port) in __hvs_find_socket_on_list()
261 return p->so; in __hvs_find_socket_on_list()
265 if (p->so != NULL && in __hvs_find_socket_on_list()
266 addr->hvs_port == p->local_addr.hvs_port) in __hvs_find_socket_on_list()
267 return p->so; in __hvs_find_socket_on_list()
288 addr->sa_family = AF_HYPERV; in hvs_addr_set()
289 addr->sa_len = sizeof(*addr); in hvs_addr_set()
290 addr->hvs_port = port; in hvs_addr_set()
316 /* Don't even give us a chance to attach on non-HyperV. */ in hvs_dom_probe()
353 if (so->so_type != SOCK_STREAM) in hvs_trans_attach()
365 pcb->so = so; in hvs_trans_attach()
366 so->so_pcb = (void *)pcb; in hvs_trans_attach()
391 so->so_pcb = NULL; in hvs_trans_detach()
414 if (sa->sa_family != AF_HYPERV) { in hvs_trans_bind()
417 __func__, sa->sa_family); in hvs_trans_bind()
420 if (sa->sa_len != sizeof(*sa)) { in hvs_trans_bind()
423 __func__, sa->sa_len); in hvs_trans_bind()
428 "%s: binding port = 0x%x\n", __func__, sa->hvs_port); in hvs_trans_bind()
439 hvs_addr_set(&pcb->local_addr, sa->hvs_port); in hvs_trans_bind()
440 hvs_addr_set(&pcb->remote_addr, HVADDR_PORT_ANY); in hvs_trans_bind()
462 bound_so = hvs_find_socket_on_list(&pcb->local_addr, HVS_LIST_BOUND); in hvs_trans_listen()
491 memcpy(sa, &pcb->remote_addr, pcb->remote_addr.sa_len); in hvs_trans_accept()
506 __func__, raddr->hvs_port); in hvs_trans_connect()
514 if (raddr->sa_family != AF_HYPERV) in hvs_trans_connect()
516 if (raddr->sa_len != sizeof(*raddr)) in hvs_trans_connect()
520 if (so->so_state & in hvs_trans_connect()
530 * Find an available port for us to auto bind the local in hvs_trans_connect()
533 hvs_addr_set(&pcb->local_addr, 0); in hvs_trans_connect()
535 for (i = previous_auto_bound_port - 1; in hvs_trans_connect()
536 i != previous_auto_bound_port; i --) { in hvs_trans_connect()
540 pcb->local_addr.hvs_port = i; in hvs_trans_connect()
542 if (__hvs_find_socket_on_list(&pcb->local_addr, in hvs_trans_connect()
548 __func__, pcb->local_addr.hvs_port); in hvs_trans_connect()
554 /* Found available port for auto bound, put on list */ in hvs_trans_connect()
557 pcb->vm_srv_id = srv_id_template; in hvs_trans_connect()
558 set_port_by_srv_id(&pcb->vm_srv_id, pcb->local_addr.hvs_port); in hvs_trans_connect()
560 pcb->host_srv_id = srv_id_template; in hvs_trans_connect()
561 set_port_by_srv_id(&pcb->host_srv_id, raddr->hvs_port); in hvs_trans_connect()
562 hvs_addr_set(&pcb->remote_addr, raddr->hvs_port); in hvs_trans_connect()
568 "%s: No local port available for auto bound\n", in hvs_trans_connect()
574 hvsock_print_guid(&pcb->vm_srv_id); in hvs_trans_connect()
576 hvsock_print_guid(&pcb->host_srv_id); in hvs_trans_connect()
582 vmbus_req_tl_connect(&pcb->vm_srv_id, &pcb->host_srv_id); in hvs_trans_connect()
603 if ((so->so_state & SS_ISDISCONNECTED) == 0) in hvs_trans_disconnect()
630 if (so->so_type != SOCK_STREAM) in hvs_trans_soreceive()
644 if (uio->uio_resid == 0 || uio->uio_rw != UIO_READ) in hvs_trans_soreceive()
647 orig_resid = uio->uio_resid; in hvs_trans_soreceive()
657 sb = &so->so_rcv; in hvs_trans_soreceive()
667 if ((sb->sb_state & SBS_CANTRCVMORE) && in hvs_trans_soreceive()
668 (so->so_state & SS_ISDISCONNECTED)) { in hvs_trans_soreceive()
675 while (uio->uio_resid > 0 && in hvs_trans_soreceive()
677 to_read = MIN(canread, uio->uio_resid); in hvs_trans_soreceive()
681 pcb->recv_data_off)); in hvs_trans_soreceive()
683 error = vmbus_chan_recv_peek_call(pcb->chan, to_read, in hvs_trans_soreceive()
684 sizeof(struct hvs_pkt_header) + pcb->recv_data_off, in hvs_trans_soreceive()
692 if (error || so->so_state & SS_ISDISCONNECTED) { in hvs_trans_soreceive()
696 pcb->recv_data_len -= to_read; in hvs_trans_soreceive()
697 pcb->recv_data_off += to_read; in hvs_trans_soreceive()
704 if (so->so_error) { in hvs_trans_soreceive()
705 if (so->so_error == ESHUTDOWN && in hvs_trans_soreceive()
706 orig_resid > uio->uio_resid) { in hvs_trans_soreceive()
714 if (so->so_error != ESHUTDOWN) in hvs_trans_soreceive()
715 error = so->so_error; in hvs_trans_soreceive()
722 if (sb->sb_state & SBS_CANTRCVMORE) in hvs_trans_soreceive()
726 if (uio->uio_resid == 0) in hvs_trans_soreceive()
729 if (!(flags & MSG_WAITALL) && orig_resid > uio->uio_resid) in hvs_trans_soreceive()
733 if ((so->so_state & SS_NBIO) || in hvs_trans_soreceive()
735 if (orig_resid == uio->uio_resid) { in hvs_trans_soreceive()
756 __func__, vmbus_chan_read_available(pcb->chan)); in hvs_trans_soreceive()
764 if (so->so_error == ESHUTDOWN) { in hvs_trans_soreceive()
765 if (so->so_snd.sb_state & SBS_CANTSENDMORE) { in hvs_trans_soreceive()
776 __func__, error, so->so_error); in hvs_trans_soreceive()
793 __func__, uio->uio_resid); in hvs_trans_sosend()
795 if (so->so_type != SOCK_STREAM) in hvs_trans_sosend()
801 if (uio->uio_resid == 0 || uio->uio_rw != UIO_WRITE) in hvs_trans_sosend()
804 orig_resid = uio->uio_resid; in hvs_trans_sosend()
814 sb = &so->so_snd; in hvs_trans_sosend()
817 if ((sb->sb_state & SBS_CANTSENDMORE) || in hvs_trans_sosend()
818 so->so_error == ESHUTDOWN) { in hvs_trans_sosend()
823 while (uio->uio_resid > 0) { in hvs_trans_sosend()
827 if (orig_resid > uio->uio_resid) in hvs_trans_sosend()
831 * non-blocked io in hvs_trans_sosend()
833 if (so->so_state & SS_NBIO || in hvs_trans_sosend()
854 vmbus_chan_write_available(pcb->chan)); in hvs_trans_sosend()
859 to_write = MIN(canwrite, uio->uio_resid); in hvs_trans_sosend()
865 error = hvsock_send_data(pcb->chan, uio, to_write, sb); in hvs_trans_sosend()
889 memcpy(sa, &pcb->remote_addr, pcb->remote_addr.sa_len); in hvs_trans_peeraddr()
905 memcpy(sa, &pcb->local_addr, pcb->local_addr.sa_len); in hvs_trans_sockaddr()
925 if (so->so_state & SS_ISCONNECTED) { in hvs_trans_close()
929 (void) hvsock_send_data(pcb->chan, NULL, 0, NULL); in hvs_trans_close()
932 if (so->so_state & in hvs_trans_close()
936 pcb->chan = NULL; in hvs_trans_close()
937 pcb->so = NULL; in hvs_trans_close()
972 if (so->so_state & SS_ISCONNECTED) { in hvs_trans_abort()
989 if ((so->so_state & in hvs_trans_shutdown()
1005 if (so->so_state & SS_ISCONNECTED) { in hvs_trans_shutdown()
1008 (void) hvsock_send_data(pcb->chan, NULL, 0, in hvs_trans_shutdown()
1009 &so->so_snd); in hvs_trans_shutdown()
1017 wakeup(&so->so_timeo); in hvs_trans_shutdown()
1022 /* In the VM, we support Hyper-V Sockets with AF_HYPERV, and the endpoint is
1025 * On the host, Hyper-V Sockets are supported by Winsock AF_HYPERV:
1026 * https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-
1027 * guide/make-integration-service, and the endpoint is <VmID, ServiceId> with
1045 * The rule of writing Hyper-V Sockets apps on the host and in FreeBSD VM is:
1050 * format: <port>-facb-11e6-bd58-64006a7986d3. *
1058 * auto-generated remote port for a connect request initiated by the host's
1105 if (pcb->chan != NULL && so != NULL) { in hvsock_chan_cb()
1109 SOCKBUF_LOCK(&(so)->so_rcv); in hvsock_chan_cb()
1113 vmbus_chan_read_available(pcb->chan)); in hvsock_chan_cb()
1115 if (hvsock_chan_readable(pcb->chan)) in hvsock_chan_cb()
1118 SOCKBUF_UNLOCK(&(so)->so_rcv); in hvsock_chan_cb()
1123 SOCKBUF_LOCK(&(so)->so_snd); in hvsock_chan_cb()
1132 SOCKBUF_UNLOCK(&(so)->so_snd); in hvsock_chan_cb()
1145 struct uio *uio = arg->uio; in hvsock_br_callback()
1146 struct sockbuf *sb = arg->sb; in hvsock_br_callback()
1155 __func__, (uio->uio_rw == UIO_READ) ? "read from br":"write to br", in hvsock_br_callback()
1156 uio->uio_resid, cplen, datap); in hvsock_br_callback()
1168 __func__, uio->uio_resid, error); in hvsock_br_callback()
1214 iov[2].iov_len = pad_pktlen - hvs_pktlen; in hvsock_send_data()
1223 iov[1].iov_len = pad_pktlen - hvs_pktlen; in hvsock_send_data()
1251 if (pcb == NULL || pcb->chan == NULL) { in hvsock_canread_check()
1252 pcb->so->so_error = EIO; in hvsock_canread_check()
1257 if (pcb->recv_data_len > 0) in hvsock_canread_check()
1258 return (pcb->recv_data_len); in hvsock_canread_check()
1260 if (pcb->rb_init) in hvsock_canread_check()
1262 VMBUS_CHANPKT_GETLEN(pcb->hvs_pkt.chan_pkt_hdr.cph_tlen); in hvsock_canread_check()
1266 bytes_canread = vmbus_chan_read_available(pcb->chan); in hvsock_canread_check()
1272 if (pcb->rb_init && bytes_canread == (advance + sizeof(uint64_t))) { in hvsock_canread_check()
1278 error = vmbus_chan_recv_idxadv(pcb->chan, advance); in hvsock_canread_check()
1285 pcb->rb_init = false; in hvsock_canread_check()
1286 pcb->recv_data_len = 0; in hvsock_canread_check()
1287 pcb->recv_data_off = 0; in hvsock_canread_check()
1288 bytes_canread = vmbus_chan_read_available(pcb->chan); in hvsock_canread_check()
1306 error = vmbus_chan_recv_peek(pcb->chan, &pcb->hvs_pkt, in hvsock_canread_check()
1320 tlen = VMBUS_CHANPKT_GETLEN(pcb->hvs_pkt.chan_pkt_hdr.cph_tlen); in hvsock_canread_check()
1321 hlen = VMBUS_CHANPKT_GETLEN(pcb->hvs_pkt.chan_pkt_hdr.cph_hlen); in hvsock_canread_check()
1322 dlen = pcb->hvs_pkt.vmpipe_pkt_hdr.vmpipe_data_size; in hvsock_canread_check()
1329 pcb->so->so_error = EIO; in hvsock_canread_check()
1332 if (pcb->rb_init == false) in hvsock_canread_check()
1333 pcb->rb_init = true; in hvsock_canread_check()
1344 pcb->so->so_error = ESHUTDOWN; in hvsock_canread_check()
1350 pcb->recv_data_len = dlen; in hvsock_canread_check()
1351 pcb->recv_data_off = 0; in hvsock_canread_check()
1353 return (pcb->recv_data_len); in hvsock_canread_check()
1362 if (pcb == NULL || pcb->chan == NULL) in hvsock_canwrite_check()
1365 writeable = vmbus_chan_write_available(pcb->chan); in hvsock_canwrite_check()
1368 * We must always reserve a 0-length-payload packet for the FIN. in hvsock_canwrite_check()
1382 ret = writeable - HVSOCK_PKT_LEN(0) - HVSOCK_PKT_LEN(0); in hvsock_canwrite_check()
1408 sndbuf = MAX(so->so_snd.sb_hiwat, HVS_RINGBUF_SND_SIZE); in hvsock_open_channel()
1411 rcvbuf = MAX(so->so_rcv.sb_hiwat, HVS_RINGBUF_RCV_SIZE); in hvsock_open_channel()
1485 new_so->so_error = error; in hvsock_open_conn_passive()
1489 pcb = so->so_pcb; in hvsock_open_conn_passive()
1490 new_pcb = new_so->so_pcb; in hvsock_open_conn_passive()
1492 hvs_addr_set(&(new_pcb->local_addr), pcb->local_addr.hvs_port); in hvsock_open_conn_passive()
1494 hvs_addr_set(&(new_pcb->remote_addr), HVADDR_PORT_UNKNOWN); in hvsock_open_conn_passive()
1495 new_pcb->chan = chan; in hvsock_open_conn_passive()
1496 new_pcb->recv_data_len = 0; in hvsock_open_conn_passive()
1497 new_pcb->recv_data_off = 0; in hvsock_open_conn_passive()
1498 new_pcb->rb_init = false; in hvsock_open_conn_passive()
1500 new_pcb->vm_srv_id = *vmbus_chan_guid_type(chan); in hvsock_open_conn_passive()
1501 new_pcb->host_srv_id = *vmbus_chan_guid_inst(chan); in hvsock_open_conn_passive()
1505 sc->pcb = new_pcb; in hvsock_open_conn_passive()
1527 so->so_error = error; in hvsock_open_conn_active()
1531 pcb = so->so_pcb; in hvsock_open_conn_active()
1532 pcb->chan = chan; in hvsock_open_conn_active()
1533 pcb->recv_data_len = 0; in hvsock_open_conn_active()
1534 pcb->recv_data_off = 0; in hvsock_open_conn_active()
1535 pcb->rb_init = false; in hvsock_open_conn_active()
1582 * the inst_guid contains the port that guest has auto bound in hvsock_open_connection()
1598 pcb = so->so_pcb; in hvsock_open_connection()
1599 if (pcb && pcb->so) { in hvsock_open_connection()
1600 sc->pcb = so2hvspcb(so); in hvsock_open_connection()
1654 int retry; in hvsock_detach() local
1661 if (sc->pcb != NULL) { in hvsock_detach()
1664 so = hsvpcb2so(sc->pcb); in hvsock_detach()
1667 if (so->so_state & in hvsock_detach()
1673 __hvs_remove_pcb_from_list(sc->pcb, in hvsock_detach()
1682 retry = 0; in hvsock_detach()
1691 "retry = %d\n", retry++); in hvsock_detach()
1693 retry = 0; in hvsock_detach()
1702 "retry = %d\n", retry++); in hvsock_detach()
1707 bzero(sc->pcb, sizeof(struct hvs_pcb)); in hvsock_detach()
1708 free(sc->pcb, M_HVSOCK); in hvsock_detach()
1709 sc->pcb = NULL; in hvsock_detach()
1714 so->so_pcb = NULL; in hvsock_detach()