]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/UdsOp.cc
7230e37b34d9775cc1128634d5b27faf36749a28
4 * DEBUG: section 54 Interprocess Communication
11 #include "CommCalls.h"
12 #include "comm/Connection.h"
13 #include "comm/Write.h"
14 #include "base/TextException.h"
15 #include "ipc/UdsOp.h"
18 Ipc :: UdsOp :: UdsOp ( const String
& pathAddr
):
19 AsyncJob ( "Ipc::UdsOp" ),
20 address ( PathToAddress ( pathAddr
)),
21 options ( COMM_NONBLOCKING
)
23 debugs ( 54 , 5 , HERE
<< '[' << this << "] pathAddr=" << pathAddr
);
28 debugs ( 54 , 5 , HERE
<< '[' << this << ']' );
29 if ( Comm :: IsConnOpen ( conn_
))
34 void Ipc :: UdsOp :: setOptions ( int newOptions
)
39 Comm :: ConnectionPointer
&
42 if (! Comm :: IsConnOpen ( conn_
)) {
43 if ( options
& COMM_DOBIND
)
44 unlink ( address
. sun_path
);
46 conn_
= new Comm :: Connection
;
47 conn_
-> fd
= comm_open_uds ( SOCK_DGRAM
, 0 , & address
, options
);
48 Must ( Comm :: IsConnOpen ( conn_
));
53 void Ipc :: UdsOp :: setTimeout ( int seconds
, const char * handlerName
)
55 typedef CommCbMemFunT
< UdsOp
, CommTimeoutCbParams
> Dialer
;
56 AsyncCall :: Pointer handler
= asyncCall ( 54 , 5 , handlerName
,
57 Dialer ( CbcPointer
< UdsOp
>( this ), & UdsOp :: noteTimeout
));
58 commSetConnTimeout ( conn (), seconds
, handler
);
61 void Ipc :: UdsOp :: clearTimeout ()
63 commUnsetConnTimeout ( conn ());
66 void Ipc :: UdsOp :: noteTimeout ( const CommTimeoutCbParams
&)
68 timedout (); // our kid handles communication timeout
73 Ipc :: PathToAddress ( const String
& pathAddr
) {
74 assert ( pathAddr
. size () != 0 );
75 struct sockaddr_un unixAddr
;
76 memset (& unixAddr
, 0 , sizeof ( unixAddr
));
77 unixAddr
. sun_family
= AF_LOCAL
;
78 xstrncpy ( unixAddr
. sun_path
, pathAddr
. termedBuf (), sizeof ( unixAddr
. sun_path
));
83 CBDATA_NAMESPACED_CLASS_INIT ( Ipc
, UdsSender
);
85 Ipc :: UdsSender :: UdsSender ( const String
& pathAddr
, const TypedMsgHdr
& aMessage
):
88 retries ( 10 ), // TODO: make configurable?
89 timeout ( 10 ), // TODO: make configurable?
92 message
. address ( address
);
95 void Ipc :: UdsSender :: start ()
100 setTimeout ( timeout
, "Ipc::UdsSender::noteTimeout" );
103 bool Ipc :: UdsSender :: doneAll () const
105 return ! writing
&& UdsOp :: doneAll ();
108 void Ipc :: UdsSender :: write ()
111 typedef CommCbMemFunT
< UdsSender
, CommIoCbParams
> Dialer
;
112 AsyncCall :: Pointer writeHandler
= JobCallback ( 54 , 5 ,
113 Dialer
, this , UdsSender :: wrote
);
114 Comm :: Write ( conn (), message
. raw (), message
. size (), writeHandler
, NULL
);
118 void Ipc :: UdsSender :: wrote ( const CommIoCbParams
& params
)
120 debugs ( 54 , 5 , HERE
<< params
. conn
<< " flag " << params
. flag
<< " retries " << retries
<< " [" << this << ']' );
122 if ( params
. flag
!= COMM_OK
&& retries
-- > 0 ) {
123 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?
124 write (); // XXX: should we close on error so that conn() reopens?
128 void Ipc :: UdsSender :: timedout ()
131 mustStop ( "timedout" );
135 void Ipc :: SendMessage ( const String
& toAddress
, const TypedMsgHdr
& message
)
137 AsyncJob :: Start ( new UdsSender ( toAddress
, message
));
140 const Comm :: ConnectionPointer
&
141 Ipc :: ImportFdIntoComm ( const Comm :: ConnectionPointer
& conn
, int socktype
, int protocol
, Ipc :: FdNoteId noteId
)
143 struct sockaddr_in addr
;
144 socklen_t len
= sizeof ( addr
);
145 if ( getsockname ( conn
-> fd
, reinterpret_cast < sockaddr
*>(& addr
), & len
) == 0 ) {
147 struct addrinfo
* addr_info
= NULL
;
148 conn
-> remote
. GetAddrInfo ( addr_info
);
149 addr_info
-> ai_socktype
= socktype
;
150 addr_info
-> ai_protocol
= protocol
;
151 comm_import_opened ( conn
, Ipc :: FdNote ( noteId
), addr_info
);
152 conn
-> remote
. FreeAddrInfo ( addr_info
);
154 debugs ( 54 , DBG_CRITICAL
, "ERROR: Ipc::ImportFdIntoComm: " << conn
<< ' ' << xstrerror ());