Mercurial > hg > freeDiameter-dtls
comparison libfdcore/sctp.c @ 1186:56c36d1007b4 dtls_dev
Further preparation of the DTLS integration. Some cleanups in the GNUTLS handling.
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Fri, 07 Jun 2013 18:48:34 +0800 |
parents | 2da13c87baa7 |
children | 823829bf1037 |
comparison
equal
deleted
inserted
replaced
1185:23695957bfc0 | 1186:56c36d1007b4 |
---|---|
1077 | 1077 |
1078 /* Done! */ | 1078 /* Done! */ |
1079 return 0; | 1079 return 0; |
1080 } | 1080 } |
1081 | 1081 |
1082 /* Send a buffer over a specified stream */ | 1082 /* Send a vector over a specified stream */ |
1083 int fd_sctp_sendstr(struct cnxctx * conn, uint16_t strid, uint8_t * buf, size_t len) | 1083 ssize_t fd_sctp_sendstrv(struct cnxctx * conn, uint16_t strid, const struct iovec *iov, int iovcnt) |
1084 { | 1084 { |
1085 struct msghdr mhdr; | 1085 struct msghdr mhdr; |
1086 struct iovec iov; | |
1087 struct cmsghdr *hdr; | 1086 struct cmsghdr *hdr; |
1088 #ifdef OLD_SCTP_SOCKET_API | 1087 #ifdef OLD_SCTP_SOCKET_API |
1089 struct sctp_sndrcvinfo *sndrcv; | 1088 struct sctp_sndrcvinfo *sndrcv; |
1090 uint8_t anci[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; | 1089 uint8_t anci[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; |
1091 #else /* OLD_SCTP_SOCKET_API */ | 1090 #else /* OLD_SCTP_SOCKET_API */ |
1093 uint8_t anci[CMSG_SPACE(sizeof(struct sctp_sndinfo))]; | 1092 uint8_t anci[CMSG_SPACE(sizeof(struct sctp_sndinfo))]; |
1094 #endif /* OLD_SCTP_SOCKET_API */ | 1093 #endif /* OLD_SCTP_SOCKET_API */ |
1095 ssize_t ret; | 1094 ssize_t ret; |
1096 int timedout = 0; | 1095 int timedout = 0; |
1097 | 1096 |
1098 TRACE_ENTRY("%p %hu %p %zd", conn, strid, buf, len); | 1097 TRACE_ENTRY("%p %hu %p %d", conn, strid, iov, iovcnt); |
1099 CHECK_PARAMS(conn && buf && len); | 1098 CHECK_PARAMS_DO(conn && iov && iovcnt, { errno = EINVAL; return -1; } ); |
1100 | 1099 |
1101 memset(&mhdr, 0, sizeof(mhdr)); | 1100 memset(&mhdr, 0, sizeof(mhdr)); |
1102 memset(&iov, 0, sizeof(iov)); | |
1103 memset(&anci, 0, sizeof(anci)); | 1101 memset(&anci, 0, sizeof(anci)); |
1104 | |
1105 /* IO Vector: message data */ | |
1106 iov.iov_base = buf; | |
1107 iov.iov_len = len; | |
1108 | 1102 |
1109 /* Anciliary data: specify SCTP stream */ | 1103 /* Anciliary data: specify SCTP stream */ |
1110 hdr = (struct cmsghdr *)anci; | 1104 hdr = (struct cmsghdr *)anci; |
1111 hdr->cmsg_len = sizeof(anci); | 1105 hdr->cmsg_len = sizeof(anci); |
1112 hdr->cmsg_level = IPPROTO_SCTP; | 1106 hdr->cmsg_level = IPPROTO_SCTP; |
1121 #endif /* OLD_SCTP_SOCKET_API */ | 1115 #endif /* OLD_SCTP_SOCKET_API */ |
1122 /* note : we could store other data also, for example in .sinfo_ppid for remote peer or in .sinfo_context for errors. */ | 1116 /* note : we could store other data also, for example in .sinfo_ppid for remote peer or in .sinfo_context for errors. */ |
1123 | 1117 |
1124 /* We don't use mhdr.msg_name here; it could be used to specify an address different from the primary */ | 1118 /* We don't use mhdr.msg_name here; it could be used to specify an address different from the primary */ |
1125 | 1119 |
1126 mhdr.msg_iov = &iov; | 1120 mhdr.msg_iov = (struct iovec *)iov; |
1127 mhdr.msg_iovlen = 1; | 1121 mhdr.msg_iovlen = iovcnt; |
1128 | 1122 |
1129 mhdr.msg_control = anci; | 1123 mhdr.msg_control = anci; |
1130 mhdr.msg_controllen = sizeof(anci); | 1124 mhdr.msg_controllen = sizeof(anci); |
1131 | 1125 |
1132 TRACE_DEBUG(FULL, "Sending %zdb data on stream %hu of socket %d", len, strid, conn->cc_socket); | 1126 TRACE_DEBUG(FULL, "Sending %d chunks of data (first:%zdb) on stream %hu of socket %d", iovcnt, iov[0].iov_len, strid, conn->cc_socket); |
1133 again: | 1127 again: |
1134 ret = sendmsg(conn->cc_socket, &mhdr, 0); | 1128 ret = sendmsg(conn->cc_socket, &mhdr, 0); |
1135 /* Handle special case of timeout */ | 1129 /* Handle special case of timeout */ |
1136 if ((ret < 0) && ((errno == EAGAIN) || (errno == EINTR))) { | 1130 if ((ret < 0) && ((errno == EAGAIN) || (errno == EINTR))) { |
1137 pthread_testcancel(); | 1131 pthread_testcancel(); |
1141 timedout ++; /* allow for one timeout while closing */ | 1135 timedout ++; /* allow for one timeout while closing */ |
1142 goto again; | 1136 goto again; |
1143 } | 1137 } |
1144 } | 1138 } |
1145 | 1139 |
1146 CHECK_SYS( ret ); | 1140 CHECK_SYS_DO( ret, ); /* for tracing error only */ |
1147 ASSERT( ret == len ); /* There should not be partial delivery with sendmsg... */ | 1141 |
1148 | 1142 return ret; |
1149 return 0; | |
1150 } | 1143 } |
1151 | 1144 |
1152 /* Receive the next data from the socket, or next notification */ | 1145 /* Receive the next data from the socket, or next notification */ |
1153 int fd_sctp_recvmeta(struct cnxctx * conn, uint16_t * strid, uint8_t ** buf, size_t * len, int *event) | 1146 int fd_sctp_recvmeta(struct cnxctx * conn, uint16_t * strid, uint8_t ** buf, size_t * len, int *event) |
1154 { | 1147 { |