1
-
2
1
{-# LANGUAGE AllowAmbiguousTypes #-}
3
2
{-# LANGUAGE CPP #-}
3
+ {-# LANGUAGE FlexibleInstances #-}
4
4
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5
+ {-# LANGUAGE OverloadedStrings #-}
5
6
{-# LANGUAGE PatternSynonyms #-}
6
7
{-# LANGUAGE RecordWildCards #-}
7
8
{-# LANGUAGE ScopedTypeVariables #-}
@@ -70,8 +71,8 @@ pattern CmsgIdIPv6PktInfo = CmsgId (#const IPPROTO_IPV6) (#const IPV6_PKTINFO)
70
71
-- | Control message ID for POSIX file-descriptor passing.
71
72
--
72
73
-- Not supported on Windows; use WSADuplicateSocket instead
73
- pattern CmsgIdFd :: CmsgId
74
- pattern CmsgIdFd = CmsgId (- 1 ) (- 1 )
74
+ pattern CmsgIdFds :: CmsgId
75
+ pattern CmsgIdFds = CmsgId (- 1 ) (- 1 )
75
76
76
77
----------------------------------------------------------------
77
78
@@ -91,11 +92,13 @@ filterCmsg cid cmsgs = filter (\cmsg -> cmsgId cmsg == cid) cmsgs
91
92
----------------------------------------------------------------
92
93
93
94
-- | A class to encode and decode control message.
94
- class Storable a => ControlMessage a where
95
+ class ControlMessage a where
95
96
controlMessageId :: CmsgId
97
+ encodeCmsg :: a -> Cmsg
98
+ decodeCmsg :: Cmsg -> Maybe a
96
99
97
- encodeCmsg :: forall a . ControlMessage a => a -> Cmsg
98
- encodeCmsg x = unsafeDupablePerformIO $ do
100
+ encodeStorableCmsg :: forall a . ( ControlMessage a , Storable a ) => a -> Cmsg
101
+ encodeStorableCmsg x = unsafeDupablePerformIO $ do
99
102
bs <- create siz $ \ p0 -> do
100
103
let p = castPtr p0
101
104
poke p x
@@ -104,8 +107,8 @@ encodeCmsg x = unsafeDupablePerformIO $ do
104
107
where
105
108
siz = sizeOf x
106
109
107
- decodeCmsg :: forall a . (ControlMessage a , Storable a ) => Cmsg -> Maybe a
108
- decodeCmsg (Cmsg cmsid (PS fptr off len))
110
+ decodeStorableCmsg :: forall a . (ControlMessage a , Storable a ) => Cmsg -> Maybe a
111
+ decodeStorableCmsg (Cmsg cmsid (PS fptr off len))
109
112
| cid /= cmsid = Nothing
110
113
| len < siz = Nothing
111
114
| otherwise = unsafeDupablePerformIO $ withForeignPtr fptr $ \ p0 -> do
@@ -122,6 +125,8 @@ newtype IPv4TTL = IPv4TTL DWORD deriving (Eq, Show, Storable)
122
125
123
126
instance ControlMessage IPv4TTL where
124
127
controlMessageId = CmsgIdIPv4TTL
128
+ decodeCmsg = decodeStorableCmsg
129
+ encodeCmsg = encodeStorableCmsg
125
130
126
131
----------------------------------------------------------------
127
132
@@ -130,6 +135,8 @@ newtype IPv6HopLimit = IPv6HopLimit DWORD deriving (Eq, Show, Storable)
130
135
131
136
instance ControlMessage IPv6HopLimit where
132
137
controlMessageId = CmsgIdIPv6HopLimit
138
+ encodeCmsg = encodeStorableCmsg
139
+ decodeCmsg = decodeStorableCmsg
133
140
134
141
----------------------------------------------------------------
135
142
@@ -138,6 +145,8 @@ newtype IPv4TOS = IPv4TOS DWORD deriving (Eq, Show, Storable)
138
145
139
146
instance ControlMessage IPv4TOS where
140
147
controlMessageId = CmsgIdIPv4TOS
148
+ encodeCmsg = encodeStorableCmsg
149
+ decodeCmsg = decodeStorableCmsg
141
150
142
151
----------------------------------------------------------------
143
152
@@ -146,6 +155,8 @@ newtype IPv6TClass = IPv6TClass DWORD deriving (Eq, Show, Storable)
146
155
147
156
instance ControlMessage IPv6TClass where
148
157
controlMessageId = CmsgIdIPv6TClass
158
+ encodeCmsg = encodeStorableCmsg
159
+ decodeCmsg = decodeStorableCmsg
149
160
150
161
----------------------------------------------------------------
151
162
@@ -158,6 +169,8 @@ instance Show IPv4PktInfo where
158
169
159
170
instance ControlMessage IPv4PktInfo where
160
171
controlMessageId = CmsgIdIPv4PktInfo
172
+ encodeCmsg = encodeStorableCmsg
173
+ decodeCmsg = decodeStorableCmsg
161
174
162
175
instance Storable IPv4PktInfo where
163
176
sizeOf ~ _ = # {size IN_PKTINFO }
@@ -180,6 +193,8 @@ instance Show IPv6PktInfo where
180
193
181
194
instance ControlMessage IPv6PktInfo where
182
195
controlMessageId = CmsgIdIPv6PktInfo
196
+ decodeCmsg = decodeStorableCmsg
197
+ encodeCmsg = encodeStorableCmsg
183
198
184
199
instance Storable IPv6PktInfo where
185
200
sizeOf ~ _ = # {size IN6_PKTINFO }
@@ -192,8 +207,14 @@ instance Storable IPv6PktInfo where
192
207
n :: ULONG <- (# peek IN6_PKTINFO , ipi6_ifindex) p
193
208
return $ IPv6PktInfo (fromIntegral n) ha6
194
209
195
- instance ControlMessage Fd where
196
- controlMessageId = CmsgIdFd
210
+ ----------------------------------------------------------------
211
+
212
+ instance ControlMessage [Fd ] where
213
+ controlMessageId = CmsgIdFds
214
+ encodeCmsg = \ _ -> Cmsg CmsgIdFds " "
215
+ decodeCmsg = \ _ -> Just []
216
+
217
+ ----------------------------------------------------------------
197
218
198
219
cmsgIdBijection :: Bijection CmsgId String
199
220
cmsgIdBijection =
@@ -204,7 +225,7 @@ cmsgIdBijection =
204
225
, (CmsgIdIPv6TClass , " CmsgIdIPv6TClass" )
205
226
, (CmsgIdIPv4PktInfo , " CmsgIdIPv4PktInfo" )
206
227
, (CmsgIdIPv6PktInfo , " CmsgIdIPv6PktInfo" )
207
- , (CmsgIdFd , " CmsgIdFd " )
228
+ , (CmsgIdFds , " CmsgIdFds " )
208
229
]
209
230
210
231
instance Show CmsgId where
0 commit comments