/*
- * Copyright (c) 2012-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2012-2017 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
INP_ADD_STAT(inp, cell, wifi, wired, rxpackets, 1);
INP_ADD_STAT(inp, cell, wifi, wired, rxbytes, data_len);
}
+ inp_set_activity_bitmap(inp);
}
static errno_t
if (signing_id != NULL) {
uint16_t result = NULL_TRIE_IDX;
lck_rw_lock_shared(&fd_cb->group->lck);
- result = flow_divert_trie_search(&fd_cb->group->signing_id_trie, (uint8_t *)signing_id);
+ if (fd_cb->group->flags & FLOW_DIVERT_GROUP_FLAG_NO_APP_MAP) {
+ result = 1;
+ } else {
+ result = flow_divert_trie_search(&fd_cb->group->signing_id_trie, (uint8_t *)signing_id);
+ }
lck_rw_done(&fd_cb->group->lck);
if (result != NULL_TRIE_IDX) {
error = 0;
}
} else {
FDLOG0(LOG_WARNING, fd_cb, "Failed to get the code signing identity");
+ if (fd_cb->group->flags & FLOW_DIVERT_GROUP_FLAG_NO_APP_MAP) {
+ error = 0;
+ }
}
if (src_proc != PROC_NULL) {
if (fd_cb->local_address != NULL) {
/* socket is bound. */
error = flow_divert_packet_append_tlv(connect_packet, FLOW_DIVERT_TLV_LOCAL_ADDR,
- sizeof(struct sockaddr_storage), fd_cb->local_address);
+ fd_cb->local_address->sa_len, fd_cb->local_address);
if (error) {
goto done;
}
}
}
- last = m_last(packet);
- mbuf_setnext(last, data);
- mbuf_pkthdr_adjustlen(packet, data_len);
+ if (data_len > 0 && data != NULL) {
+ last = m_last(packet);
+ mbuf_setnext(last, data);
+ mbuf_pkthdr_adjustlen(packet, data_len);
+ }
error = flow_divert_send_packet(fd_cb, packet, force);
if (error) {
}
}
data_len = mbuf_pkthdr_len(m);
- FDLOG(LOG_DEBUG, fd_cb, "mbuf_copym() data_len = %lu", data_len);
- error = mbuf_copym(m, 0, data_len, MBUF_DONTWAIT, &data);
- if (error) {
- FDLOG(LOG_ERR, fd_cb, "mbuf_copym failed: %d", error);
- break;
+ if (data_len > 0) {
+ FDLOG(LOG_DEBUG, fd_cb, "mbuf_copym() data_len = %lu", data_len);
+ error = mbuf_copym(m, 0, data_len, MBUF_DONTWAIT, &data);
+ if (error) {
+ FDLOG(LOG_ERR, fd_cb, "mbuf_copym failed: %d", error);
+ break;
+ }
+ } else {
+ data = NULL;
}
error = flow_divert_send_data_packet(fd_cb, data, data_len, toaddr, force);
if (error) {
}
}
} else if (SOCK_TYPE(fd_cb->so) == SOCK_DGRAM) {
- if (to_send) {
+ if (to_send || mbuf_pkthdr_len(data) == 0) {
error = flow_divert_send_data_packet(fd_cb, data, to_send, toaddr, FALSE);
if (error) {
FDLOG(LOG_ERR, fd_cb, "flow_divert_send_data_packet failed. send data size = %lu", to_send);
static mbuf_t
flow_divert_get_control_mbuf(struct flow_divert_pcb *fd_cb)
{
- struct inpcb *inp = sotoinpcb(fd_cb->so);
- if (inp->inp_vflag & INP_IPV4 && inp->inp_flags & INP_RECVDSTADDR) {
- struct sockaddr_in *sin = (struct sockaddr_in *)(void *)fd_cb->local_address;
+ if (fd_cb->local_address != NULL) {
+ struct inpcb *inp = sotoinpcb(fd_cb->so);
+ if (inp->inp_vflag & INP_IPV4 && inp->inp_flags & INP_RECVDSTADDR) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)(void *)fd_cb->local_address;
- return sbcreatecontrol((caddr_t) &sin->sin_addr, sizeof(struct in_addr), IP_RECVDSTADDR, IPPROTO_IP);
- } else if (inp->inp_vflag & INP_IPV6 && (inp->inp_flags & IN6P_PKTINFO) != 0) {
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)(void *)fd_cb->local_address;
- struct in6_pktinfo pi6;
+ return sbcreatecontrol((caddr_t) &sin->sin_addr, sizeof(struct in_addr), IP_RECVDSTADDR, IPPROTO_IP);
+ } else if (inp->inp_vflag & INP_IPV6 && (inp->inp_flags & IN6P_PKTINFO) != 0) {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)(void *)fd_cb->local_address;
+ struct in6_pktinfo pi6;
- bcopy(&sin6->sin6_addr, &pi6.ipi6_addr, sizeof (struct in6_addr));
- pi6.ipi6_ifindex = 0;
- return sbcreatecontrol((caddr_t)&pi6, sizeof (struct in6_pktinfo), IPV6_PKTINFO, IPPROTO_IPV6);
+ bcopy(&sin6->sin6_addr, &pi6.ipi6_addr, sizeof (struct in6_addr));
+ pi6.ipi6_ifindex = 0;
+ return sbcreatecontrol((caddr_t)&pi6, sizeof (struct in6_pktinfo), IPV6_PKTINFO, IPPROTO_IPV6);
+ }
}
return (NULL);
}
}
}
socket_unlock(fd_cb->so, 0);
-
- if (data != NULL) {
- mbuf_freem(data);
- }
}
FDUNLOCK(fd_cb);
}
int error = 0;
uint32_t key_size = 0;
int log_level;
+ uint32_t flags = 0;
error = flow_divert_packet_get_tlv(packet, offset, FLOW_DIVERT_TLV_TOKEN_KEY, 0, NULL, &key_size);
if (error) {
group->token_key_size = key_size;
+ error = flow_divert_packet_get_tlv(packet, offset, FLOW_DIVERT_TLV_FLAGS, sizeof(flags), &flags, NULL);
+ if (!error) {
+ group->flags = flags;
+ }
+
lck_rw_done(&group->lck);
}
}
static int
-flow_divert_connectx_out_common(struct socket *so, int af,
- struct sockaddr_list **src_sl, struct sockaddr_list **dst_sl,
- struct proc *p, uint32_t ifscope __unused, sae_associd_t aid __unused,
- sae_connid_t *pcid, uint32_t flags __unused, void *arg __unused,
- uint32_t arglen __unused, struct uio *auio, user_ssize_t *bytes_written)
+flow_divert_connectx_out_common(struct socket *so, struct sockaddr *dst,
+ struct proc *p, sae_connid_t *pcid, struct uio *auio, user_ssize_t *bytes_written)
{
- struct sockaddr_entry *src_se = NULL, *dst_se = NULL;
struct inpcb *inp = sotoinpcb(so);
int error;
return (EINVAL);
}
- VERIFY(dst_sl != NULL);
-
- /* select source (if specified) and destination addresses */
- error = in_selectaddrs(af, src_sl, &src_se, dst_sl, &dst_se);
- if (error != 0) {
- return (error);
- }
-
- VERIFY(*dst_sl != NULL && dst_se != NULL);
- VERIFY(src_se == NULL || *src_sl != NULL);
- VERIFY(dst_se->se_addr->sa_family == af);
- VERIFY(src_se == NULL || src_se->se_addr->sa_family == af);
+ VERIFY(dst != NULL);
- error = flow_divert_connect_out(so, dst_se->se_addr, p);
+ error = flow_divert_connect_out(so, dst, p);
if (error != 0) {
return error;
}
static int
-flow_divert_connectx_out(struct socket *so, struct sockaddr_list **src_sl,
- struct sockaddr_list **dst_sl, struct proc *p, uint32_t ifscope,
- sae_associd_t aid, sae_connid_t *pcid, uint32_t flags, void *arg,
- uint32_t arglen, struct uio *uio, user_ssize_t *bytes_written)
+flow_divert_connectx_out(struct socket *so, struct sockaddr *src __unused,
+ struct sockaddr *dst, struct proc *p, uint32_t ifscope __unused,
+ sae_associd_t aid __unused, sae_connid_t *pcid, uint32_t flags __unused, void *arg __unused,
+ uint32_t arglen __unused, struct uio *uio, user_ssize_t *bytes_written)
{
-#pragma unused(uio, bytes_written)
- return (flow_divert_connectx_out_common(so, AF_INET, src_sl, dst_sl,
- p, ifscope, aid, pcid, flags, arg, arglen, uio, bytes_written));
+ return (flow_divert_connectx_out_common(so, dst, p, pcid, uio, bytes_written));
}
#if INET6
static int
-flow_divert_connectx6_out(struct socket *so, struct sockaddr_list **src_sl,
- struct sockaddr_list **dst_sl, struct proc *p, uint32_t ifscope,
- sae_associd_t aid, sae_connid_t *pcid, uint32_t flags, void *arg,
- uint32_t arglen, struct uio *uio, user_ssize_t *bytes_written)
+flow_divert_connectx6_out(struct socket *so, struct sockaddr *src __unused,
+ struct sockaddr *dst, struct proc *p, uint32_t ifscope __unused,
+ sae_associd_t aid __unused, sae_connid_t *pcid, uint32_t flags __unused, void *arg __unused,
+ uint32_t arglen __unused, struct uio *uio, user_ssize_t *bytes_written)
{
-#pragma unused(uio, bytes_written)
- return (flow_divert_connectx_out_common(so, AF_INET6, src_sl, dst_sl,
- p, ifscope, aid, pcid, flags, arg, arglen, uio, bytes_written));
+ return (flow_divert_connectx_out_common(so, dst, p, pcid, uio, bytes_written));
}
#endif /* INET6 */
fd_cb->flags |= FLOW_DIVERT_CONNECT_STARTED;
}
- so->so_flags1 &= ~SOF1_PRECONNECT_DATA;
+ soclearfastopen(so);
return error;
}
error = soopt_getm(sopt, &token);
if (error) {
+ token = NULL;
goto done;
}
error = soopt_mcopyin(sopt, token);
if (error) {
+ token = NULL;
goto done;
}
error = flow_divert_packet_get_tlv(token, 0, FLOW_DIVERT_TLV_KEY_UNIT, sizeof(key_unit), (void *)&key_unit, NULL);
if (!error) {
key_unit = ntohl(key_unit);
+ if (key_unit >= GROUP_COUNT_MAX) {
+ key_unit = 0;
+ }
} else if (error != ENOENT) {
FDLOG(LOG_ERR, &nil_pcb, "Failed to get the key unit from the token: %d", error);
goto done;