00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef INNERSOCKET_H
00026 #define INNERSOCKET_H
00027
00028 #include <unistd.h>
00029 #include <netinet/in.h>
00030 #include <arpa/inet.h>
00031 #include <string.h>
00032 #include <iostream>
00033 #include <sys/socket.h>
00034 #include <sys/un.h>
00035 #include <errno.h>
00036 #include <stdlib.h>
00037 #include <DCDT_Defs.h>
00038 #include <DCDT_Msg.h>
00039
00040
00041
00042 class InnerSocket
00043 {
00044 public:
00045 InnerSocket()
00046 {
00047 sockfd = opened = bound = connected = tconn_flag = tlost_flag = tsend_flag = trecv_flag = 0;
00048 tconn_value.tv_sec = tconn_value.tv_usec = tlost_value.tv_sec = tlost_value.tv_usec = 0;
00049 tsend_value.tv_sec = tsend_value.tv_usec = trecv_value.tv_sec = trecv_value.tv_usec = 0;
00050 unblock_send_flag = unblock_recv_flag = 0;
00051 name = NULL;
00052 };
00053
00054 ~InnerSocket()
00055 {
00056 if ( name )
00057 delete[] name;
00058 };
00059
00060 inline void Open();
00061 inline void Bind(char *n);
00062 inline void Connect(char *n);
00063 inline void Send(const DCDT_Msg *msg);
00064 inline DCDT_Msg* Receive();
00065 inline void SendHS(char *to, HSMsgHeader *header, char* payload);
00066 inline void ReceiveHS(HSMsgHeader*& header, char*& payload);
00067 inline void Close();
00068 inline void ForcedClose();
00069 inline void SetLostTimer(int usec);
00070 inline void LostTimerOn();
00071 inline void LostTimerOff();
00072 inline void SetConnTimer(int usec);
00073 inline void ConnTimerOn();
00074 inline void ConnTimerOff();
00075 inline void SetSendTimer(int usec);
00076 inline void SendTimerOn();
00077 inline void SendTimerOff();
00078 inline void UnblockSend();
00079 inline void SetReceiveTimer(int usec);
00080 inline void ReceiveTimerOn();
00081 inline void ReceiveTimerOff();
00082 inline void UnblockReceive();
00083
00084 protected:
00085 int sockfd, opened, bound, connected, tconn_flag, tlost_flag, tsend_flag, trecv_flag;
00086 int unblock_send_flag, unblock_recv_flag;
00087 struct timeval tconn_value, tlost_value, tsend_value, trecv_value;
00088 char *name;
00089 };
00090
00091 inline void InnerSocket::Open()
00092 {
00093 if (opened)
00094 return;
00095
00096 if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
00097 throw ChannelError(errno);
00098
00099 opened = 1;
00100
00101 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("InnerSocket successfully opened"));
00102 }
00103
00104 inline void InnerSocket::Bind(char *n)
00105 {
00106 struct sockaddr_un addr;
00107
00108 if (!opened || bound || !n)
00109 return;
00110
00111 if (name)
00112 delete[] name;
00113
00114 name = new char[strlen(n) + 1];
00115 strcpy(name, n);
00116
00117 memset(&addr, 0, sizeof(addr));
00118 strcpy(addr.sun_path, name);
00119
00120 addr.sun_family = AF_UNIX;
00121
00122 remove(n);
00123 if (bind(sockfd, (struct sockaddr *) &addr, strlen(addr.sun_path) + sizeof (addr.sun_family)) < 0)
00124 throw ChannelError(errno);
00125
00126 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("InnerSocket successfully bound to: %s", name));
00127
00128 bound = 1;
00129 }
00130
00131 inline void InnerSocket::Connect(char *n)
00132 {
00133 struct sockaddr_un addr;
00134
00135 if (!opened || connected)
00136 return;
00137
00138 memset(&addr, 0, sizeof(addr));
00139 strcpy(addr.sun_path, n);
00140
00141 addr.sun_family = AF_UNIX;
00142 if (connect(sockfd, (struct sockaddr *)&addr, strlen(addr.sun_path) + sizeof (addr.sun_family)) < 0)
00143 throw ConnError(errno);
00144
00145 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("InnerSocket successfully connected to: %s", n));
00146
00147 connected = 1;
00148 }
00149
00150 inline void InnerSocket::Send(const DCDT_Msg* msg)
00151 {
00152 fd_set wset;
00153 struct timeval tv, *tv_ptr = NULL;
00154 msghdr mh;
00155 iovec iov[1];
00156 int nsent;
00157
00158 if (!opened || !connected)
00159 return;
00160
00161 FD_ZERO(&wset);
00162 FD_SET(sockfd, &wset);
00163 if (unblock_send_flag)
00164 {
00165 tv.tv_sec = 0;
00166 tv.tv_usec = 0;
00167 tv_ptr = &tv;
00168 }
00169 else if (tsend_flag)
00170 {
00171 tv.tv_sec = tsend_value.tv_sec;
00172 tv.tv_usec = tsend_value.tv_usec;
00173 tv_ptr = &tv;
00174 }
00175 else if (tlost_flag)
00176 {
00177 tv.tv_sec = tlost_value.tv_sec;
00178 tv.tv_usec = tlost_value.tv_usec;
00179 tv_ptr = &tv;
00180 }
00181 switch (select(sockfd+1, NULL, &wset, NULL, tv_ptr))
00182 {
00183 case 0: throw TimeOut();
00184 case -1: throw ConnError(errno);
00185 }
00186
00187
00188 memset(&mh, 0, sizeof(mh));
00189 iov[0].iov_base = msg->GetHeader();
00190 iov[0].iov_len = MSGHEADER_LEN;
00191 mh.msg_iov = iov;
00192 mh.msg_iovlen = 1;
00193
00194 if ((nsent = sendmsg(sockfd, &mh, 0)) < 0)
00195 throw ConnError(errno);
00196 else if (nsent != MSGHEADER_LEN ) {
00197
00198 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Inner bytes sent: %i", nsent));
00199
00200 throw ConnError();
00201 }
00202
00203 iov[0].iov_base = msg->GetPayload();
00204 iov[0].iov_len = msg->ReadPayloadLen();
00205 if ((nsent = sendmsg(sockfd, &mh, 0)) < 0)
00206 throw ConnError(errno);
00207 else if (nsent != (int)iov[0].iov_len) {
00208
00209 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Inner bytes sent: %i", nsent));
00210
00211 throw ConnError();
00212 }
00213
00214 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Inner bytes sent: %i message successfully sent", nsent));
00215
00216 }
00217
00218 inline void InnerSocket::SendHS(char *to, HSMsgHeader *header, char* payload)
00219 {
00220 fd_set wset;
00221 struct timeval tv, *tv_ptr = NULL;
00222 struct sockaddr_un addr;
00223 msghdr mh;
00224 iovec iov[2];
00225 int nsent;
00226
00227 if (!opened)
00228 return;
00229
00230 FD_ZERO(&wset);
00231 FD_SET(sockfd, &wset);
00232 if (unblock_send_flag)
00233 {
00234 tv.tv_sec = 0;
00235 tv.tv_usec = 0;
00236 tv_ptr = &tv;
00237 }
00238 else if (tsend_flag)
00239 {
00240 tv.tv_sec = tsend_value.tv_sec;
00241 tv.tv_usec = tsend_value.tv_usec;
00242 tv_ptr = &tv;
00243 }
00244 else if (tlost_flag)
00245 {
00246 tv.tv_sec = tlost_value.tv_sec;
00247 tv.tv_usec = tlost_value.tv_usec;
00248 tv_ptr = &tv;
00249 }
00250 switch (select(sockfd+1, NULL, &wset, NULL, tv_ptr))
00251 {
00252 case 0: throw TimeOut();
00253 case -1: throw ConnError(errno);
00254 }
00255
00256 memset(&addr, 0, sizeof(addr));
00257 strcpy(addr.sun_path, to);
00258 addr.sun_family = AF_UNIX;
00259
00260 memset(&mh, 0, sizeof(mh));
00261 mh.msg_name = &addr;
00262 mh.msg_namelen = sizeof(addr);
00263
00264 iov[0].iov_base = header;
00265 iov[0].iov_len = HSMSGHEADER_LEN;
00266 iov[1].iov_base = payload;
00267 header->payload_len = iov[1].iov_len = strlen(payload)+1;
00268
00269 mh.msg_iov = iov;
00270 mh.msg_iovlen = 2;
00271
00272 if ((nsent = sendmsg(sockfd, &mh, 0)) < 0)
00273 throw ConnError(errno);
00274 else if (nsent < (int)(iov[0].iov_len + iov[1].iov_len)) {
00275
00276 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Inner bytes sent: %i", nsent));
00277
00278 throw ConnError();
00279 }
00280
00281 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Inner bytes sent: %i message successfully sent", nsent));
00282 }
00283
00284
00285 inline DCDT_Msg* InnerSocket::Receive()
00286 {
00287 DCDT_MsgHeader *msg_header;
00288 int plen;
00289 DCDT_Msg *msg;
00290 void *buf;
00291 msghdr mh;
00292 iovec iov[1];
00293
00294 int nread = 0;
00295 fd_set rset;
00296 struct timeval tv, *tv_ptr = NULL;
00297
00298 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("InnerSocket::Receive"));
00299
00300 if (!opened)
00301 return NULL;
00302
00303 FD_ZERO(&rset);
00304 FD_SET(sockfd, &rset);
00305 if (unblock_recv_flag)
00306 {
00307 tv.tv_sec = 0;
00308 tv.tv_usec = 0;
00309 tv_ptr = &tv;
00310 }
00311 else if (trecv_flag)
00312 {
00313 tv.tv_sec = trecv_value.tv_sec;
00314 tv.tv_usec = trecv_value.tv_usec;
00315 tv_ptr = &tv;
00316 }
00317 else if (tlost_flag)
00318 {
00319 tv.tv_sec = tlost_value.tv_sec;
00320 tv.tv_usec = tlost_value.tv_usec;
00321 tv_ptr = &tv;
00322 }
00323 switch (select(sockfd+1, &rset, NULL, NULL, tv_ptr)) {
00324 case 0: return NULL;
00325 case -1: throw ConnError(errno);
00326 }
00327
00328
00329 memset(&mh, 0, sizeof(mh));
00330 msg_header = new DCDT_MsgHeader;
00331 iov[0].iov_base = msg_header;
00332 iov[0].iov_len = MSGHEADER_LEN;
00333 mh.msg_iov = iov;
00334 mh.msg_iovlen = 1;
00335 if ((nread = recvmsg(sockfd, &mh, 0)) < 0) {
00336 delete msg_header;
00337 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("recvmsg error %d", nread));
00338 throw ConnError(errno);
00339 }
00340 else if (nread == 0 || nread != (int)MSGHEADER_LEN) {
00341 delete msg_header;
00342 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("recvmsg error %d", nread));
00343 throw ConnError();
00344 }
00345
00346 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Inner byte read: %i", nread));
00347
00348 msg = new DCDT_Msg(msg_header);
00349 plen = msg->ReadPayloadLen();
00350 buf = malloc ( plen );
00351 memset ( buf, 0, plen );
00352 iov[0].iov_base = buf;
00353 iov[0].iov_len = plen;
00354 mh.msg_iov = iov;
00355 mh.msg_iovlen = 1;
00356 if ((nread = recvmsg(sockfd, &mh, 0)) != plen ) {
00357 free(buf);
00358 delete msg_header;
00359 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("recvmsg error %d", nread));
00360 throw ConnError(errno);
00361 }
00362
00363 msg->SetPayload( buf, plen );
00364
00365 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Inner message successfully received"));
00366
00367 return msg;
00368 }
00369
00370 inline void InnerSocket::ReceiveHS(HSMsgHeader*& header, char*& payload)
00371 {
00372 HSMsgHeader *msg_header;
00373 char *data;
00374 msghdr mh;
00375 iovec iov[2];
00376
00377 int nread = 0;
00378 fd_set rset;
00379 struct timeval tv, *tv_ptr = NULL;
00380
00381 if (!opened)
00382 return;
00383
00384 FD_ZERO(&rset);
00385 FD_SET(sockfd, &rset);
00386 if (unblock_recv_flag)
00387 {
00388 tv.tv_sec = 0;
00389 tv.tv_usec = 0;
00390 tv_ptr = &tv;
00391 }
00392 else if (trecv_flag)
00393 {
00394 tv.tv_sec = trecv_value.tv_sec;
00395 tv.tv_usec = trecv_value.tv_usec;
00396 tv_ptr = &tv;
00397 }
00398 else if (tlost_flag)
00399 {
00400 tv.tv_sec = tlost_value.tv_sec;
00401 tv.tv_usec = tlost_value.tv_usec;
00402 tv_ptr = &tv;
00403 }
00404 switch (select(sockfd+1, &rset, NULL, NULL, tv_ptr)) {
00405 case 0:
00406 throw TimeOut();
00407 case -1:
00408 throw ConnError(errno);
00409 }
00410
00411
00412 memset(&mh, 0, sizeof(mh));
00413 msg_header = new HSMsgHeader();
00414 data = new char[UNIX_PATH_MAX];
00415 iov[0].iov_base = msg_header;
00416 iov[0].iov_len = HSMSGHEADER_LEN;
00417 iov[1].iov_base = data;
00418 iov[1].iov_len = UNIX_PATH_MAX;
00419 mh.msg_iov = iov;
00420 mh.msg_iovlen = 2;
00421 if ((nread = recvmsg(sockfd, &mh, 0)) < 0) {
00422 delete[] data;
00423 delete msg_header;
00424 throw ConnError(errno);
00425 }
00426 else if (nread == 0 || nread < (int)HSMSGHEADER_LEN) {
00427 delete[] data;
00428 delete msg_header;
00429 throw ConnError();
00430 }
00431
00432 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Inner byte read: %i", nread));
00433
00434 if (nread < (int)(HSMSGHEADER_LEN + (msg_header->payload_len))) {
00435 delete[] data;
00436 delete msg_header;
00437 throw ConnError();
00438 }
00439
00440 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Inner message successfully received"));
00441
00442 if ( header != NULL )
00443 printf ( "InnerSocket.h: header != NULL\n" );
00444
00445 header = msg_header;
00446 payload = new char[msg_header->payload_len];
00447 memcpy(payload, data, msg_header->payload_len);
00448 delete[] data;
00449 }
00450
00454 inline void InnerSocket::Close()
00455 {
00456 if (opened) {
00457 if (close(sockfd) < 0)
00458 throw ConnError(errno);
00459 connected = opened = bound = sockfd = 0;
00460 remove(name);
00461
00462 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("InnerSocket successfully closed"));
00463 }
00464 }
00465
00466 inline void InnerSocket::ForcedClose()
00467 {
00468 if (opened) {
00469 shutdown(sockfd, SHUT_RDWR);
00470 connected = opened = bound = sockfd = 0;
00471 remove(name);
00472
00473 TRC_PRINT( DCDT_TRC_COMM, TRC1, ("InnerSocket successfully shut"));
00474 }
00475 }
00476
00477
00478 inline void InnerSocket::SetLostTimer(int usec)
00479 {
00480 tlost_value.tv_usec = usec % 1000000;
00481 tlost_value.tv_sec = usec / 1000000;
00482 };
00483
00484 inline void InnerSocket::LostTimerOn()
00485 {
00486 tlost_flag = 1;
00487 };
00488
00489 inline void InnerSocket::LostTimerOff()
00490 {
00491 tlost_flag = 0;
00492 };
00493
00494 inline void InnerSocket::SetConnTimer(int usec)
00495 {
00496 tconn_value.tv_usec = usec % 1000000;
00497 tconn_value.tv_sec = usec / 1000000;
00498 };
00499
00500 inline void InnerSocket::ConnTimerOn()
00501 {
00502 tconn_flag = 1;
00503 };
00504
00505 inline void InnerSocket::ConnTimerOff()
00506 {
00507 tconn_flag = 0;
00508 };
00509
00510 inline void InnerSocket::SetSendTimer(int usec)
00511 {
00512 tsend_value.tv_usec = usec % 1000000;
00513 tsend_value.tv_sec = usec / 1000000;
00514 };
00515
00516 inline void InnerSocket::SendTimerOn()
00517 {
00518 tsend_flag = 1;
00519 unblock_send_flag = 0;
00520 };
00521
00522 inline void InnerSocket::SendTimerOff()
00523 {
00524 tsend_flag = 0;
00525 };
00526
00527 inline void InnerSocket::UnblockSend()
00528 {
00529 unblock_send_flag = 1;
00530 }
00531
00532 inline void InnerSocket::SetReceiveTimer(int usec)
00533 {
00534 trecv_value.tv_usec = usec % 1000000;
00535 trecv_value.tv_sec = usec / 1000000;
00536 };
00537
00538 inline void InnerSocket::ReceiveTimerOn()
00539 {
00540 trecv_flag = 1;
00541 unblock_recv_flag = 0;
00542 };
00543
00544 inline void InnerSocket::ReceiveTimerOff()
00545 {
00546 trecv_flag = 0;
00547 };
00548
00549 inline void InnerSocket::UnblockReceive()
00550 {
00551 unblock_recv_flag = 1;
00552 }
00553
00554 #endif