Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 314318 Details for
Bug 458712
RH 5.2 - SCTP Messages out of order
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
code that performs BIND operation
bind.txt (text/plain), 9.08 KB, created by
William Reich
on 2008-08-14 14:02:36 UTC
(
hide
)
Description:
code that performs BIND operation
Filename:
MIME Type:
Creator:
William Reich
Created:
2008-08-14 14:02:36 UTC
Size:
9.08 KB
patch
obsolete
>/************************************************************ > >FUNCTION > int > sctp_do_socket_and_bind(sctp_link_t *plink) > >DESCRIPTION > This function performs actual bind assuming that > everything is set-up. > >INPUTS > Arg: plink => sctp end-point object. > Others: None > >OUTPUTS > Return: -1 if failure, 0 if success > Arg: None > Others: None > >************************************************************/ >int >sctp_do_socket_and_bind(sctp_link_t *plink) >{ > struct sctp_event_subscribe e; > struct sockaddr *sockaddr; > struct sockaddr_in in4; > struct sockaddr_in6 in6; > socklen_t socklen; > int error = 0; > bool use_ephemeral_port = false; > > > /* > * Something seriously wrong if this function > * is invoked on an already created socket > */ > if ( plink->native_sctp_fd != -1 ) > { > ULCM_WARN("[id=%d] %s native_sctp_fd != -1 !!", plink->id, __func__ ); > error = EPROTO; > goto error; > } > > if ( plink->local_addr.ip_addr_count == 0 ) > { > ULCM_WARN("[id=%d] %s ip_addr_count == 0 !!", plink->id, __func__ ); > error = EINVAL; > goto error; > } > > /* > * Create IPv6 socket. > * IPv6 socket support both IPv4 and IPv6 addresses. > * NOTICE: Remember that PF_INET6 socket will map > * IPv4 addresses into IPv6 representation when doing > * sctp_recvmsg() > */ > plink->native_sctp_fd = socket(PF_INET6, SOCK_STREAM, IPPROTO_SCTP); > if (plink->native_sctp_fd == -1) > { > /* > * Maybe resources are not available at this time, > * let the user try again. > */ > error = errno; > ULCM_WARN("[id=%d] socket() failed, errno = %d(%s)", > plink->id, error, strerror(error) ); > goto error; > } > > > /* > * If true it means we are re-binding a socket > * that was bound using ephemeral port > */ > if(plink->use_ephem_port) > { > plink->local_addr.port = htons(0); > } > > if(plink->debug) > { > ULCM_MSG("[id=%d] %s is attempting to bind to:", > plink->id, __func__ ); > sctp_addr_print(&plink->local_addr, stderr); > } > > /* > * Bind to the first address > */ > if ( plink->local_addr.ip_addr[0].ip_version == 4 ) > { > memset(&in4, 0, sizeof(in4)); > in4.sin_family = AF_INET; > in4.sin_port = plink->local_addr.port; > in4.sin_addr = plink->local_addr.ip_addr[0].addr.ipv4; > sockaddr = (struct sockaddr *) &in4; > socklen = sizeof(in4); > } > else /* IPv6 */ > { > memset(&in6, 0, sizeof(in6)); > in6.sin6_family = AF_INET6; > in6.sin6_port = plink->local_addr.port; > in6.sin6_addr = plink->local_addr.ip_addr[0].addr.ipv6; > sockaddr = (struct sockaddr *) &in6; > socklen = sizeof(in6); > } > /* > * [SCTP] Fix bug in setting ephemeral port in the bind address. > * http://linux-lksctp.bkbits.net:8080/lksctp-2.5.work/ > * cset@41d2029eGcoI_qaM1-hSrZDdgnmY7w > * > * This is bug fix is currently not available in the latest SLES9 > * patch. > */ > if ( bind(plink->native_sctp_fd, sockaddr, socklen) == -1) > { > error = errno; > goto error; > } > > /* > * When user specifies zero port to bind, it means > * that LKSCTP will allocate ephemeral port, and > * after the first bind() we can retrieve this > * port number and use it for the remaining IP addresses > * (if any) > */ > if ( ntohs(plink->local_addr.port) == 0 ) > { > use_ephemeral_port = true; > sockaddr = (struct sockaddr *) &in6; > socklen = sizeof(in6); > if ( getsockname(plink->native_sctp_fd, > sockaddr, > &socklen) == -1 ) > { > error = errno; > ULCM_WARN("[id=%d] getsockname() failed, errno = %d(%s)", > plink->id, error, strerror(error) ); > /* > * This should never happen, if it does, close > * the socket and let the user try again. > */ > goto error; > } > plink->local_addr.port = in6.sin6_port; > SCTP_DYNAMIC_DEBUG("[id=%d] using ephemeral SCTP port = %u", > plink->id, ntohs(plink->local_addr.port) ); > } > > /* > * Bind to the remaining addresses (if any) > */ > for(int i = 1; i < plink->local_addr.ip_addr_count; i++ ) > { > if (plink->local_addr.ip_addr[i].ip_version == 4) > { > memset(&in4, 0, sizeof(in4)); > in4.sin_family = AF_INET; > in4.sin_port = plink->local_addr.port; > in4.sin_addr = plink->local_addr.ip_addr[i].addr.ipv4; > sockaddr = (struct sockaddr *) &in4; > } > else /* IPv6 */ > { > memset(&in6, 0, sizeof(in6)); > in6.sin6_family = AF_INET6; > in6.sin6_port = plink->local_addr.port; > in6.sin6_addr = plink->local_addr.ip_addr[i].addr.ipv6; > sockaddr = (struct sockaddr *) &in6; > } > > if ( sctp_bindx(plink->native_sctp_fd, > sockaddr, > 1, > SCTP_BINDX_ADD_ADDR) == -1) > > { > error = errno; > SCTP_DYNAMIC_DEBUG("[id=%d] sctp_bindx() failed," > " errno = %d(%s)", plink->id, error, strerror(error) ); > /* > * Bind failed. Close this socket and send NACK. > * Let the user try again if he wishes. > */ > goto error; > } > } > > /* > * Print some debugging info. if debugging is enabled > */ > if(plink->debug) > { > int ret; > sockaddr = NULL; > > if( (ret = sctp_getladdrs(plink->native_sctp_fd, 0, &sockaddr)) == -1) > { > error = errno; > ULCM_WARN("sctp_getladdrs() failed, errno = %d", error ); > goto error; > } > ULCM_MSG("[id=%d] sctp_getladdrs() - bound to %d IP addr", > plink->id, ret ); > if(sockaddr) > { > sctp_freeladdrs(sockaddr); > } > } > > /* > * Now that the bind was successful, need to subscibe > * to some SCTP events. Events will be processed on upstream > * thread. > */ > memset(&e, 0, sizeof(e) ); > e.sctp_data_io_event = 1; /* SCTP_SNDRCV info on a per msg basis */ > e.sctp_address_event = 1; /* SCTP_PEER_ADDR_CHANGE */ > e.sctp_association_event = 1; /* SCTP_ASSOC_CHANGE */ > e.sctp_shutdown_event = 1; /* SCTP_SHUTDOWN_EVENT */ > >#if _NOT_COMPILED_COMPILED >/* > * >OK, so you are saying that "message expiry" is the > * >only realistic case when you can get SCTP_SEND_FAILED > * >and never get SCTP_COMM_LOST (before or after)? > * >So if I disable message expiry option, then I should > * >NEVER get SCTP_SEND_FAILED before getting > * >SCTP_COMM_LOST? > * > * Yes. > * -Sridhar > * > * Based on the above correspondence, this event will be disabled. > * The only time we can get this event when sctp_sendmsg() fails. > * In other cases we will get SCTP_COMM_DOWN first, which will > * imeadeatly abort the association. > */ >// e.sctp_send_failure_event = 1; /* SCTP_SEND_FAILED */ >#endif > > if ( setsockopt(plink->native_sctp_fd, > IPPROTO_SCTP, > SCTP_EVENTS, > &e, > sizeof(e) ) == -1) > { > /* > * If this does not work then the best we can do is to > * close the socket and NACK the bind request. > */ > error = errno; > ULCM_WARN("[id=%d] setsockopt(SCTP_EVENTS) failed, " > "errno = %d(%s)", plink->id, error, strerror(error) ); > goto error; > } > > /* Set up SCTP receiver buffer size */ > if ( grcv_buf_size && > setsockopt(plink->native_sctp_fd, > SOL_SOCKET, SO_RCVBUF, > &grcv_buf_size, sizeof(grcv_buf_size)) == -1 ) > > { > error = errno; > ULCM_WARN("[id=%d] setsockopt(SO_RCVBUF) failed, " > "errno = %d(%s)", plink->id, error, strerror(error) ); > goto error; > } > > /* Set up SCTP send buffer size */ > if ( gsnd_buf_size && > setsockopt(plink->native_sctp_fd, > SOL_SOCKET, SO_SNDBUF, > &gsnd_buf_size, sizeof(gsnd_buf_size)) == -1 ) > > { > error = errno; > ULCM_WARN("[id=%d] setsockopt(SO_SNDBUF) failed, " > "errno = %d(%s)", plink->id, error, strerror(error) ); > goto error; > } > > > /* > * Make sure that default behaivor of close() will > * send abort. > * NOTICE: Remmeber that close() will be done each time > * downstream thread terminates and native_sctp_fd != -1 > * If you need gracefull shutdown, need to perform shutdown(). > */ > if ( sctp_set_linger_abort(plink->native_sctp_fd) == -1) > { > /* > * If this does not work then the best we can do is to > * close the socket and NACK the bind request. > */ > error = errno; > ULCM_WARN("[id=%d] setsockopt(SO_LINGER) failed, " > "errno = %d(%s)", plink->id, error, strerror(error) ); > goto error; > } > > /* > * Each time we bind a socket, we use provisioning information > * stored in the end-point. When we create a new sctp end-point > * it will be initialized to default ULCM SCTP values. > */ > if ( sctp_set_initmsg(plink) == -1) > { > error = errno; > ULCM_WARN("[id=%d] sctp_set_initmsg() failed, " > "errno = %d(%s)", plink->id, error, strerror(error) ); > goto error; > } > > if ( sctp_set_rto(plink) == -1) > { > error = errno; > ULCM_WARN("[id=%d] sctp_set_rto() failed, " > "errno = %d(%s)", plink->id, error, strerror(error) ); > goto error; > } > > if (use_ephemeral_port) > { > plink->use_ephem_port = 1; > } > > /* success */ > return 0; > > /* failure */ >error: > /* > * When socket() and/or bind() fails, we always go > * back to IDLE state, this is the best we can do. > * NOTICE: ulcm_sctp_close() is safe for fd == -1. > */ > if ( (ulcm_sctp_close(&plink->native_sctp_fd) == -1) && (errno == EINTR) ) > { > error = errno; > } > sctp_link_set_state(plink, ULCM_LKSCTP_IDLE); > plink->bound = 0; > plink->use_ephem_port = 0; > errno = error; > > return -1; >} > >/* EOF */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 458712
: 314318 |
314625