]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/UdsOp.cc
2 * DEBUG: section 54 Interprocess Communication
9 #include "comm/Connection.h"
10 #include "comm/Write.h"
11 #include "base/TextException.h"
12 #include "ipc/UdsOp.h"
14 Ipc :: UdsOp :: UdsOp ( const String
& pathAddr
):
15 AsyncJob ( "Ipc::UdsOp" ),
16 address ( PathToAddress ( pathAddr
)),
17 options ( COMM_NONBLOCKING
)
19 debugs ( 54 , 5 , HERE
<< '[' << this << "] pathAddr=" << pathAddr
);
24 debugs ( 54 , 5 , HERE
<< '[' << this << ']' );
25 if ( Comm :: IsConnOpen ( conn_
))
30 void Ipc :: UdsOp :: setOptions ( int newOptions
)
35 Comm :: ConnectionPointer
&
38 if (! Comm :: IsConnOpen ( conn_
)) {
39 if ( options
& COMM_DOBIND
)
40 unlink ( address
. sun_path
);
42 conn_
= new Comm :: Connection
;
43 conn_
-> fd
= comm_open_uds ( SOCK_DGRAM
, 0 , & address
, options
);
44 Must ( Comm :: IsConnOpen ( conn_
));
49 void Ipc :: UdsOp :: setTimeout ( int seconds
, const char * handlerName
)
51 typedef CommCbMemFunT
< UdsOp
, CommTimeoutCbParams
> Dialer
;
52 AsyncCall :: Pointer handler
= asyncCall ( 54 , 5 , handlerName
,
53 Dialer ( CbcPointer
< UdsOp
>( this ), & UdsOp :: noteTimeout
));
54 commSetConnTimeout ( conn (), seconds
, handler
);
57 void Ipc :: UdsOp :: clearTimeout ()
59 commUnsetConnTimeout ( conn ());
62 void Ipc :: UdsOp :: noteTimeout ( const CommTimeoutCbParams
&)
64 timedout (); // our kid handles communication timeout
68 Ipc :: PathToAddress ( const String
& pathAddr
) {
69 assert ( pathAddr
. size () != 0 );
70 struct sockaddr_un unixAddr
;
71 memset (& unixAddr
, 0 , sizeof ( unixAddr
));
72 unixAddr
. sun_family
= AF_LOCAL
;
73 xstrncpy ( unixAddr
. sun_path
, pathAddr
. termedBuf (), sizeof ( unixAddr
. sun_path
));
77 CBDATA_NAMESPACED_CLASS_INIT ( Ipc
, UdsSender
);
79 Ipc :: UdsSender :: UdsSender ( const String
& pathAddr
, const TypedMsgHdr
& aMessage
):
82 retries ( 10 ), // TODO: make configurable?
83 timeout ( 10 ), // TODO: make configurable?
86 message
. address ( address
);
89 void Ipc :: UdsSender :: start ()
94 setTimeout ( timeout
, "Ipc::UdsSender::noteTimeout" );
97 bool Ipc :: UdsSender :: doneAll () const
99 return ! writing
&& UdsOp :: doneAll ();
102 void Ipc :: UdsSender :: write ()
105 typedef CommCbMemFunT
< UdsSender
, CommIoCbParams
> Dialer
;
106 AsyncCall :: Pointer writeHandler
= JobCallback ( 54 , 5 ,
107 Dialer
, this , UdsSender :: wrote
);
108 Comm :: Write ( conn (), message
. raw (), message
. size (), writeHandler
, NULL
);
112 void Ipc :: UdsSender :: wrote ( const CommIoCbParams
& params
)
114 debugs ( 54 , 5 , HERE
<< params
. conn
<< " flag " << params
. flag
<< " retries " << retries
<< " [" << this << ']' );
116 if ( params
. flag
!= COMM_OK
&& retries
-- > 0 ) {
117 sleep ( 1 ); // do not spend all tries at once; XXX: use an async timed event instead of blocking here; store the time when we started writing so that we do not sleep if not needed?
118 write (); // XXX: should we close on error so that conn() reopens?
122 void Ipc :: UdsSender :: timedout ()
125 mustStop ( "timedout" );
128 void Ipc :: SendMessage ( const String
& toAddress
, const TypedMsgHdr
& message
)
130 AsyncJob :: Start ( new UdsSender ( toAddress
, message
));
133 const Comm :: ConnectionPointer
&
134 Ipc :: ImportFdIntoComm ( const Comm :: ConnectionPointer
& conn
, int socktype
, int protocol
, Ipc :: FdNoteId noteId
)
136 struct sockaddr_in addr
;
137 socklen_t len
= sizeof ( addr
);
138 if ( getsockname ( conn
-> fd
, reinterpret_cast < sockaddr
*>(& addr
), & len
) == 0 ) {
140 struct addrinfo
* addr_info
= NULL
;
141 conn
-> remote
. GetAddrInfo ( addr_info
);
142 addr_info
-> ai_socktype
= socktype
;
143 addr_info
-> ai_protocol
= protocol
;
144 comm_import_opened ( conn
, Ipc :: FdNote ( noteId
), addr_info
);
145 conn
-> remote
. FreeAddrInfo ( addr_info
);
147 debugs ( 54 , DBG_CRITICAL
, "ERROR: Ipc::ImportFdIntoComm: " << conn
<< ' ' << xstrerror ());