/* Wrapper for call down to OS disconnect. */ ci_inline int ci_udp_sys_disconnect( ci_fd_t sock, citp_socket* ep ) { struct sockaddr_in sin; sin.sin_family = AF_UNSPEC; return ci_sys_connect( sock, (struct sockaddr*)&sin, sizeof(sin) ); }
static int citp_passthrough_connect(citp_fdinfo* fdi, const struct sockaddr* sa, socklen_t sa_len, citp_lib_context_t* lib_context) { int rc = ci_sys_connect(fdi_to_alien_fdi(fdi)->os_socket, sa, sa_len); citp_fdinfo_release_ref(fdi, 0); return rc; }
/* create a pt->pt association with a server * This uses the OS to do all the work so that we don't have to emulate * some of the more unpleasant "tricks" of Linux. * * When we're either handing-over OS-dest connects or when we're "no * failing" connects we may return -2 (unhandled). In this case the * OS socket _has_ been connected & we therefore are handing-over to * a socket in the right state. * * NOTE: WINDOWS the WSPConnect() API is quite a lot more complex than * the BSD one. Therefore, to stop polluting the core code with masses * of Windows frippery, the backing socket connection is successfully * established _before_ this function is called. This function will use * the state of the backing socket to configure the Efab socket - so the * end result is the same (right down to the race between the OS socket * connection being established and our filters being inserted). */ int ci_udp_connect(citp_socket* ep, ci_fd_t fd, const struct sockaddr* serv_addr, socklen_t addrlen ) { int rc; ci_fd_t os_sock; CHECK_UEP(ep); LOG_UC(log("%s("SF_FMT", addrlen=%d)", __FUNCTION__, SF_PRI_ARGS(ep,fd), addrlen)); os_sock = ci_get_os_sock_fd(fd); if( !CI_IS_VALID_SOCKET( os_sock ) ) { LOG_U(ci_log("%s: no backing socket", __FUNCTION__)); return -1; } /* Because we have not handed over the fd to the OS all calls to bind() * and connect() will have been seen by us - therefore our copies of * the local/remote address & port will be accurate. */ /* Let the OS do the connection - it'll also do the data validation * for free. On failure the OS changes nothing - therefore we * need to leave the filters in place (if such they were). * Because the OS socket and our socket are socket-options-synchronized, * the following call will also check the supplied address according to * the SO_BROADCAST socket option settings. */ rc = ci_sys_connect(os_sock, serv_addr, addrlen); if( rc != 0 ) { LOG_U(log("%s: sys_connect failed errno:%d", __FUNCTION__, errno)); ci_rel_os_sock_fd(os_sock); return -1; } rc = ci_udp_connect_conclude( ep, fd, serv_addr, addrlen, os_sock); ci_rel_os_sock_fd(os_sock); return rc; }