`Page 1/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`1
`+++++¬
`…
`¬2
`$Id: udp.c,v 1.16 2001/09/02 04:49:03 davidc Exp $¬
`3
`¬4
`Copyright (c) 2001 BeComm Corporation¬
`5
`¬6
`Filename:¬
`7
`¬8
` udp.c¬
`9
`¬10
`Abstract:¬
`11
`¬12
` The implementation of the UDP portion of the SocketLib API. This is
`13
`the¬
`…
` Win32 (NT/95/CE) version using the standard sockets interface exported¬
`14
` by WinSock.¬
`15
`¬16
`Owner:¬
`17
`¬18
` David Costanzo (davidc)¬
`19
`¬20
`--------------------------------------------------------------------------
`21
`---*/¬
`…
`¬22
`#include <windows.h>¬
`23
`#include <winsock2.h>¬
`24
`#include <process.h>¬
`25
`#include <assert.h>¬
`26
`¬27
`#define SOS_DEBUG_ZONE "/classes/socket/udp"¬
`28
`#include <sosstrings.h>¬
`29
`#include <sosisocket.h>¬
`30
`#include "socket.h"¬
`31
`#include "udp.h"¬
`32
`¬33
`SOS_SOURCE_VERSION("$Id: udp.c,v 1.16 2001/09/02 04:49:03 davidc Exp $");¬
`34
`¬35
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`36
`+++++¬
`…
`macros¬
`37
`--------------------------------------------------------------------------
`38
`---*/¬
`…
`¬39
`#define ERROR_BIND_FAILED
`40
`
`SOS_Error¬
`
`Page 1 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 2/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`#define ERROR_SOCKET_FAILED SOS_Error¬
`41
`#define ERROR_BIND_FAILED SOS_Error¬
`42
`#define ERROR_CONNECT_FAILED SOS_Error¬
`43
`#define ERROR_GETSOCKNAME_FAILED SOS_Error¬
`44
`#define ERROR_SETSOCKOPT_FAILED SOS_Error¬
`45
`¬46
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`47
`+++++¬
`…
`types¬
`48
`--------------------------------------------------------------------------
`49
`---*/¬
`…
`¬50
`typedef enum _UDP_CONNECTION_FUNCTION_ID {¬
`51
` UDP_CONNECTION_FUNCTION_ID_OnReceive,¬
`52
` UDP_CONNECTION_FUNCTION_ID_OnClose,¬
`53
`} UDP_CONNECTION_FUNCTION_ID;¬
`54
`¬55
`typedef struct _UDP_CONNECTION_PARAM UDP_CONNECTION_PARAM;¬
`56
`¬57
`¬58
`struct _UDP_CONNECTION_PARAM {¬
`59
`¬60
` UDP_CONNECTION_FUNCTION_ID FunctionId;¬
`61
`¬62
` union _UDP_CONNECTION_PARAMS {¬
`63
`¬64
` struct _UDP_CONNECTION_PARAM_ON_RECEIVE {¬
`65
` SOS_ISOCKET_UDP * Socket;¬
`66
` const SOS_ISOCKET_ADDRESS* SocketAddress;¬
`67
` void* Buffer;¬
`68
` size_t BufferLength;¬
`69
` SOS_FREEPROC BufferFree;¬
`70
` } OnReceive;¬
`71
`¬72
` struct _UDP_CONNECTION_PARAM_ON_CLOSE {¬
`73
` SOS_ISOCKET_UDP * Socket;¬
`74
` } OnClose;¬
`75
`¬76
` } Params;¬
`77
`};¬
`78
`¬79
`¬80
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`81
`+++++¬
`…
`Constants¬
`82
`
`Page 2 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 3/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`--------------------------------------------------------------------------
`83
`---*/¬
`…
`/* REVISIT: it would be nice if we could check the size¬
`84
` of the message and allocate the right amount for each¬
`85
` message instead of having to keep a big buffer around¬
`86
` and copy to a buffer of the right size each time... */¬
`87
`static const size_t g_UdpRecvSize = 65535;¬
`88
`¬89
`¬90
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`91
`+++++¬
`…
`Data Types¬
`92
`--------------------------------------------------------------------------
`93
`---*/¬
`…
`¬94
`/* UDP socket context to be passed back and forth with caller of this
`95
`library */¬
`…
`struct _SOS_ISOCKET_UDP {¬
`96
` SOCKET NativeSocket;¬
`97
` int RefCount;¬
`98
` SOS_ISOCKET_UDP_RECEIVE RecvCallback;¬
`99
` SOS_ISOCKET_CLOSED ClosedCallback;¬
`100
` struct sockaddr_in RemoteSockAddr;¬
`101
` SOS_ISOCKET_ADDRESS SocketAddr;¬
`102
` void* UserContext;¬
`103
` SOS_BOOLEAN IsCopy;¬
`104
`¬
`105
` unsigned long NativeRecvThread;¬
`106
`};¬
`107
`¬
`108
`struct _SOS_ISOCKET_UDP_LISTEN {¬
`109
` SOS_ISOCKET_UDP Socket;¬
`110
`};¬
`111
`¬
`112
`¬
`113
`¬
`114
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`115
`+++++¬
`…
`Internal Routines¬
`116
`--------------------------------------------------------------------------
`117
`---*/¬
`…
`¬
`118
`/*++¬
`119
`Routine Name:¬
`120
`¬
`121
`
`Page 3 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 4/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`122
`123
`124
`125
`126
`127
`128
`129
`130
`131
`132
`133
`134
`135
`136
`137
`138
`139
`140
`141
`142
`143
`144
`145
`146
`147
`148
`149
`150
`151
`152
`153
`154
`155
`156
`157
`158
`159
`160
`161
`162
`163
`164
`165
`166
`
` UdpSocketCreate¬
`¬
`Routine Description:¬
`¬
` This routine allocates and initializes an SOS_ISOCKET_UDP struct.¬
` It does not call any sockets routines.¬
` The structure is returned with a reference count of 1.¬
`¬
`Parameters:¬
`¬
` SOCKET NativeSocket - [in]¬
` The native socket handle.¬
`¬
` SOS_ISOCKET_UDP_RECEIVE RecvCallback - [in]¬
` The user-defined RecvCallback.¬
`¬
` SOS_ISOCKET_CLOSED ClosedCallback - [in]¬
` The user-defined ClosedCallback.¬
`¬
` const struct sockaddr_in* RemoteSockAddr - [in]¬
` The remote socket address.¬
` This parameter is optional.¬
`¬
` const SOS_ISOCKET_ADDRESS* SocketAddr - [in]¬
` The socket address.¬
`¬
` void* UserContext - [in]¬
` The user context to pass into RecvCallback and ClosedCallback.¬
`¬
`Return Value:¬
`¬
` SOS_ISOCKET_UDP* -¬
` A pointer to a newly allocated SOS_ISOCKET_UDP structure with¬
` a reference count of 1.¬
` NULL, if the structure could not be created.¬
`¬
`--*/¬
`static¬
`SOS_ISOCKET_UDP*¬
`UdpSocketCreate(¬
` SOCKET NativeSocket,¬
` SOS_ISOCKET_UDP_RECEIVE RecvCallback,¬
` SOS_ISOCKET_CLOSED ClosedCallback,¬
` const struct sockaddr_in * RemoteSockAddr,¬
` const SOS_ISOCKET_ADDRESS * SocketAddr,¬
`
`Page 4 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 5/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`167
`168
`169
`170
`171
`172
`173
`174
`175
`176
`177
`178
`179
`180
`181
`182
`183
`184
`185
`186
`187
`188
`189
`190
`191
`192
`193
`194
`195
`196
`197
`198
`199
`200
`201
`202
`203
`204
`205
`206
`207
`208
`209
`210
`211
`
` void* UserContext¬
`)¬
`{¬
` SOS_ISOCKET_UDP* udpSocket;¬
`¬
` /* allocate enough size for the larger SOS_ISOCKET_UDP_LISTEN */¬
` udpSocket = malloc(sizeof(SOS_ISOCKET_UDP_LISTEN));¬
` if (udpSocket != NULL) {¬
`¬
` udpSocket->NativeSocket = NativeSocket;¬
` udpSocket->ClosedCallback = ClosedCallback;¬
` udpSocket->RecvCallback = RecvCallback;¬
` if (RemoteSockAddr) {¬
` udpSocket->RemoteSockAddr = *RemoteSockAddr;¬
` }¬
` udpSocket->SocketAddr = *SocketAddr;¬
` udpSocket->UserContext = UserContext;¬
` udpSocket->IsCopy = SOS_False;¬
`¬
` udpSocket->RefCount = 1;¬
` }¬
`¬
` return udpSocket;¬
`}¬
`¬
`/*++¬
`Routine Name:¬
`¬
` UdpSocketDestroy¬
`¬
`Routine Description:¬
`¬
` This is the SOS_FREEPROC for udp sockets. It simply unallocated¬
` the structure. It does not make any socket-specific calls, such¬
` as closing the socket handle.¬
`¬
`Parameters:¬
`¬
` SOS_ISOCKET_UDP* UdpSocket - [consumed]¬
` The UdpSocket structure to destroy.¬
`¬
`Return Value:¬
`¬
` None¬
`¬
`
`Page 5 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 6/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`212
`213
`214
`215
`216
`217
`218
`219
`220
`221
`222
`223
`224
`225
`226
`227
`228
`229
`230
`231
`232
`233
`234
`235
`236
`237
`238
`239
`240
`241
`242
`243
`244
`245
`246
`247
`248
`249
`250
`251
`252
`253
`254
`255
`256
`
`--*/¬
`static¬
`void¬
`UdpSocketDestroy(¬
` SOS_ISOCKET_UDP* UdpSocket¬
`)¬
`{¬
` if (UdpSocket) {¬
` assert(UdpSocket->RefCount == 0);¬
` free(UdpSocket);¬
` }¬
`}¬
`¬
`¬
`/*++¬
`Routine Name:¬
`¬
` UdpSocketReference¬
`¬
`Routine Description:¬
`¬
` This routine adds a reference to a UDP socket struct.¬
`¬
`Parameters:¬
`¬
` SOS_ISOCKET_UDP* UdpSocket - [in]¬
` The UDP socket whose reference count should be incremented.¬
`¬
`Return Value:¬
`¬
` SOS_ISOCKET_UDP* -¬
` The argument UdpSocket.¬
`¬
`--*/¬
`static¬
`SOS_ISOCKET_UDP*¬
`UdpSocketReference(¬
` SOS_ISOCKET_UDP* UdpSocket¬
`)¬
`{¬
` if (UdpSocket) {¬
` assert(0 < UdpSocket->RefCount);¬
` InterlockedIncrement(&UdpSocket->RefCount);¬
` }¬
`¬
`
`Page 6 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 7/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`257
`258
`259
`260
`261
`262
`263
`264
`265
`266
`267
`268
`269
`270
`271
`272
`273
`274
`…
`275
`276
`277
`278
`279
`280
`281
`282
`283
`284
`285
`286
`287
`288
`289
`290
`291
`292
`293
`294
`295
`296
`297
`298
`299
`300
`
` return UdpSocket;¬
`}¬
`¬
`¬
`/*++¬
`Routine Name:¬
`¬
` UdpSocketRelease¬
`¬
`Routine Description:¬
`¬
` This routine removes a reference from a UDP socket struct.¬
` If the reference count becomes zero, the structure is destroyed.¬
`¬
`Parameters:¬
`¬
` SOS_ISOCKET_UDP* UdpSocket - [in]¬
` The UdpSocket structure whose reference count is to be
`decremented.¬
`¬
`Return Value:¬
`¬
` None¬
`¬
`--*/¬
`static¬
`void¬
`UdpSocketRelease(¬
` SOS_ISOCKET_UDP* UdpSocket¬
`)¬
`{¬
` if (UdpSocket) {¬
`¬
` int oldValue;¬
`¬
` assert(0 < UdpSocket->RefCount);¬
`¬
` oldValue = InterlockedDecrement(&UdpSocket->RefCount);¬
` if (oldValue == 0) {¬
` UdpSocketDestroy(UdpSocket);¬
` }¬
` }¬
`}¬
`¬
`¬
`
`Page 7 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 8/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`301
`302
`303
`304
`305
`306
`307
`308
`309
`310
`311
`312
`313
`314
`315
`316
`317
`318
`319
`320
`321
`322
`323
`324
`325
`326
`327
`328
`329
`330
`331
`332
`333
`334
`335
`336
`337
`338
`339
`340
`341
`342
`343
`344
`345
`
`¬
`¬
`¬
`/*++¬
`Routine Name:¬
`¬
` UdpRecvCloseWorkerThread¬
`¬
`Thread Context:¬
`¬
` Internal¬
`¬
`Routine Description:¬
`¬
` This is a worker proc that calls into Strings. It calls¬
` both the OnReceive callback and the OnClose callback.¬
`¬
`Parameters:¬
`¬
` void* InternalThreadParams - [in]¬
` The marshalled up parameters to call the callback with.¬
`¬
`Return Value:¬
`¬
` None¬
`¬
`--*/¬
`static¬
`void¬
`UdpRecvCloseWorkerThread(¬
` void * InternalThreadParams¬
`)¬
`{¬
` UDP_CONNECTION_PARAM* const params = InternalThreadParams;¬
`¬
` switch (params->FunctionId) {¬
` case UDP_CONNECTION_FUNCTION_ID_OnReceive:¬
`¬
` params->Params.OnReceive.Socket->RecvCallback(¬
` &g_ISocket,¬
` params->Params.OnReceive.Socket,¬
` params->Params.OnReceive.SocketAddress,¬
` params->Params.OnReceive.Socket->UserContext,¬
` params->Params.OnReceive.Buffer,¬
` params->Params.OnReceive.BufferLength,¬
`
`Page 8 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 9/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`346
`347
`348
`349
`350
`351
`352
`353
`354
`355
`356
`357
`358
`359
`360
`361
`362
`363
`364
`365
`366
`367
`368
`369
`370
`371
`372
`373
`374
`375
`376
`377
`378
`379
`…
`380
`381
`382
`…
`383
`…
`384
`…
`385
`386
`
` params->Params.OnReceive.BufferFree¬
` );¬
`¬
` break;¬
`¬
` case UDP_CONNECTION_FUNCTION_ID_OnClose:¬
`¬
` params->Params.OnClose.Socket->ClosedCallback(¬
` &g_ISocket,¬
` params->Params.OnClose.Socket->UserContext¬
` );¬
`¬
` break;¬
`¬
` default:¬
` SOS_ASSERT_ASSUMPTION(0, "Can't Happen");¬
` }¬
`¬
`}¬
`¬
`¬
`/*++¬
`Routine Name:¬
`¬
` UdpRecvThread¬
`¬
`Thread Context:¬
`¬
` External¬
`¬
`Routine Description:¬
`¬
` This thread loops receiving UDP datagrams on a socket. Since UDP listen¬
` sockets are are bound only to local port number, messages for a number
`of¬
` different address 4-tuples can come into the same thread here. When a¬
` datagram is received, we call the user's RecvCallback with the data and¬
` an address struct with the address data for that particular message.
`The¬
` recvfrom() call blocks until data is ready of the socket is closed.
`NOTE:¬
` this call the the RecvCallback must be an entire UDP message, which
`could¬
` be as large as 64K. The recvfrom() call will not return more than one¬
` datagram.¬
`
`Page 9 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 10/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`387
`388
`389
`390
`391
`392
`393
`394
`395
`396
`397
`398
`399
`400
`401
`402
`403
`404
`405
`406
`407
`408
`409
`410
`411
`412
`413
`414
`415
`416
`417
`418
`419
`420
`421
`422
`423
`424
`425
`426
`427
`428
`429
`430
`431
`
`¬
`Parameters:¬
`¬
` void* Context - [in]¬
` This is the UDP socket handle that is receiving data.¬
`¬
`Return Value:¬
`¬
` unsigned -¬
` 0, always¬
`¬
`--*/¬
`static¬
`unsigned¬
`__stdcall¬
`UdpRecvThread(¬
` void * Context¬
`)¬
`{¬
` SOS_ISOCKET_UDP* const socketContext = Context;¬
`¬
` SOS_ISOCKET_ADDRESS socketAddr;¬
` SOS_INT32 ret;¬
` SOS_INT32 remotesize;¬
` struct sockaddr_in saddr_remote;¬
` void* bigBuffer;¬
` void* littleBuffer;¬
`¬
`¬
` /* REVISIT: We allocate a 64K buffer (since that is the largest¬
` possible UDP packet) and receive an entire UDP message into it.¬
` Then, we see how big the message is, allocate an appropriately¬
` sized buffer and copy the message into it. The big 64K buffer¬
` is then reused for the next message.¬
`¬
` It would be nicer if we could figure out a way to determine how¬
` big each UDP message is and allocate the correct size buffer for¬
` it and read directly into it instead of having to do the copy. */¬
`¬
` bigBuffer = malloc(g_UdpRecvSize);¬
`¬
` socketAddr = socketContext->SocketAddr;¬
`¬
` while (1) {¬
`¬
`
`Page 10 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 11/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`432
`433
`434
`435
`436
`437
`438
`439
`440
`441
`442
`443
`444
`445
`446
`447
`448
`449
`450
`451
`452
`453
`454
`455
`456
`457
`458
`459
`460
`461
`462
`463
`464
`465
`466
`467
`468
`469
`470
`471
`472
`473
`474
`475
`476
`
` UDP_CONNECTION_PARAM params;¬
`¬
` remotesize = sizeof(saddr_remote);¬
` ret = recvfrom(¬
` socketContext->NativeSocket,¬
` bigBuffer,¬
` g_UdpRecvSize,¬
` 0,¬
` (struct sockaddr*)&(saddr_remote),¬
` &remotesize);¬
`¬
` /* if the connection was closed or there was an error... */¬
` if (ret <= 0 || ret == SOCKET_ERROR) {¬
` break;¬
` }¬
`¬
` littleBuffer = malloc(ret);¬
` if (littleBuffer) {¬
` SOS_ISOCKET_UDP* socketContextCopy;¬
`¬
` memcpy(littleBuffer, bigBuffer, ret);¬
`¬
` /* fill in the address that the message was received on */¬
` socketAddr.RemoteAddr = ntohl(saddr_remote.sin_addr.s_addr);¬
` socketAddr.RemotePort = ntohs(saddr_remote.sin_port);¬
`¬
` socketContext->RemoteSockAddr = saddr_remote;¬
`¬
` /* copy the socket context for the user */¬
`¬
` /* CONSIDER for speed: a memcpy would be much faster */¬
` socketContextCopy = UdpSocketCreate(¬
` socketContext->NativeSocket,¬
` socketContext->RecvCallback,¬
` socketContext->ClosedCallback,¬
` &socketContext->RemoteSockAddr,¬
` &socketContext->SocketAddr,¬
` socketContext->UserContext);¬
` if (socketContextCopy != NULL) {¬
`¬
` socketContextCopy->IsCopy = SOS_True;¬
`¬
` params.FunctionId = UDP_CONNECTION_FUNCTION_ID_OnReceive;¬
`¬
` params.Params.OnReceive.Socket =
`
`Page 11 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 12/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`476…
`477
`478
`479
`480
`481
`482
`483
`484
`485
`486
`487
`488
`489
`490
`491
`492
`493
`494
`495
`…
`496
`497
`498
`499
`500
`501
`502
`503
`504
`505
`506
`507
`508
`509
`510
`511
`512
`513
`514
`515
`516
`517
`518
`519
`
`socketContextCopy;¬
` params.Params.OnReceive.SocketAddress = &socketAddr;¬
` params.Params.OnReceive.Buffer = littleBuffer;¬
` params.Params.OnReceive.BufferLength = ret;¬
` params.Params.OnReceive.BufferFree = free;¬
`¬
` SOS_Internal_Call(UdpRecvCloseWorkerThread, ¶ms); ¬
` }¬
` }¬
` }¬
`¬
`¬
` if (ret == SOCKET_ERROR) {¬
` HRESULT result;¬
` result = WSAGetLastError();¬
`¬
` /* BUG: (davidc)¬
` There is currently no way for PortalSock to distinguish¬
` between a half-close and a reset socket. If the socket is¬
` reset (WSA error 10054), PsUdp will think it's just a
`half-close¬
` and still try to send on this socket, which crashes.¬
` */¬
` }¬
`¬
` if (socketContext->ClosedCallback) {¬
` /* only call this for non-listen sockets */¬
`¬
` UDP_CONNECTION_PARAM params;¬
`¬
` params.FunctionId = UDP_CONNECTION_FUNCTION_ID_OnClose;¬
` params.Params.OnClose.Socket = socketContext;¬
`¬
` SOS_Internal_Call(UdpRecvCloseWorkerThread, ¶ms);¬
` }¬
`¬
`¬
` UdpSocketRelease(socketContext);¬
` free(bigBuffer);¬
`¬
` return 0;¬
`}¬
`¬
`¬
`¬
`
`Page 12 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 13/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`520
`…
`521
`522
`…
`523
`524
`525
`526
`527
`528
`529
`530
`531
`532
`533
`534
`535
`536
`537
`538
`539
`540
`541
`542
`543
`544
`545
`546
`547
`548
`549
`550
`551
`552
`553
`554
`555
`556
`557
`558
`559
`560
`561
`562
`
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++++¬
`SocketLib API -- UDP¬
`--------------------------------------------------------------------------
`---*/¬
`/* create a UDP socket to send on and start a recv thread¬
` to get any incoming data on that socket */¬
`¬
`SOS_STATUS¬
`Socket_UdpCreate(¬
` SOS_ISOCKET* Interface,¬
` SOS_ISOCKET_ADDRESS* SocketAddr,¬
` void* UserContext,¬
` SOS_ISOCKET_UDP_RECEIVE RecvCallback,¬
` SOS_ISOCKET_CLOSED ClosedCallback,¬
` SOS_ISOCKET_UDP** Socket¬
`)¬
`{¬
` SOS_STATUS status = SOS_ErrorParameter;¬
`¬
` if (Socket != NULL) {¬
`¬
` SOCKET nativeSocket;¬
` struct sockaddr_in saddr_local;¬
` struct sockaddr_in saddr_remote;¬
` int ret, size;¬
` SOS_ISOCKET_UDP* context;¬
` int optionValue;¬
`¬
` unsigned threadAddr;¬
`¬
` *Socket = NULL;¬
`¬
` saddr_local.sin_family = PF_INET;¬
` saddr_local.sin_port = htons(SocketAddr->LocalPort);¬
` saddr_local.sin_addr.s_addr = htonl(INADDR_ANY);¬
`¬
` memset(&saddr_remote, 0, sizeof(saddr_remote));¬
` saddr_remote.sin_family = PF_INET;¬
` saddr_remote.sin_port = htons(SocketAddr->RemotePort);¬
` saddr_remote.sin_addr.s_addr = htonl(SocketAddr->RemoteAddr);¬
`¬
` /* Create a UDP socket. */¬
` nativeSocket = socket(PF_INET, SOCK_DGRAM, 0);¬
` if (nativeSocket == INVALID_SOCKET) {¬
`
`Page 13 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 14/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`563
`564
`565
`566
`567
`568
`569
`570
`571
`572
`573
`574
`575
`576
`577
`578
`579
`580
`581
`582
`…
`583
`584
`585
`586
`587
`588
`589
`590
`…
`591
`592
`593
`594
`595
`596
`597
`598
`599
`600
`601
`602
`603
`604
`605
`
` return ERROR_SOCKET_FAILED;¬
` }¬
`¬
` /* Enable broadcast on this socket */¬
` if (SocketAddr->RemoteAddr == INADDR_BROADCAST) {¬
` optionValue = SOS_True;¬
` ret = setsockopt(¬
` nativeSocket,¬
` SOL_SOCKET,¬
` SO_BROADCAST,¬
` (char *)&optionValue,¬
` sizeof(optionValue));¬
` if (ret == SOCKET_ERROR) {¬
` closesocket(nativeSocket);¬
` return ERROR_SETSOCKOPT_FAILED;¬
` }¬
` }¬
`¬
` /* Bind the socket to the local address */¬
` ret = bind(nativeSocket, (struct sockaddr*)&saddr_local,
`sizeof(saddr_local));¬
` if (ret == SOCKET_ERROR) {¬
` closesocket(nativeSocket);¬
` return ERROR_BIND_FAILED;¬
` }¬
`¬
` /* Find out the local IP used */¬
` size = sizeof(saddr_local);¬
` ret = getsockname(nativeSocket, (struct sockaddr*)&saddr_local,
`&size);¬
` if (ret == SOCKET_ERROR) {¬
` closesocket(nativeSocket);¬
` return ERROR_GETSOCKNAME_FAILED;¬
` }¬
` SocketAddr->LocalAddr = ntohl(saddr_local.sin_addr.s_addr);¬
` SocketAddr->LocalPort = ntohs(saddr_local.sin_port);¬
`¬
` /* fill my context */¬
` context = UdpSocketCreate(¬
` nativeSocket,¬
` RecvCallback,¬
` ClosedCallback,¬
` &saddr_remote,¬
` SocketAddr,¬
` UserContext);¬
`
`Page 14 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 15/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`606
`607
`608
`609
`610
`611
`612
`613
`614
`615
`616
`617
`618
`619
`620
`621
`622
`623
`624
`625
`626
`627
`628
`629
`630
`631
`632
`633
`634
`635
`636
`637
`638
`639
`640
`641
`642
`643
`644
`645
`646
`647
`648
`649
`650
`
` if (context != NULL) {¬
`¬
` /* Spawn a thread to listen for incoming messages */¬
` UdpSocketReference(context);¬
` context->NativeRecvThread = _beginthreadex(¬
` NULL, /* no security descriptor */¬
` 0, /* default stack size */¬
` UdpRecvThread,¬
` context,¬
` 0, /* no creation flags */¬
` &threadAddr /* thread ID out param */¬
` );¬
` if (context->NativeRecvThread != -1) {¬
` status = SOS_Success;¬
` }¬
` else {¬
` /* release the reference that the thread didn't take */¬
` UdpSocketRelease(context);¬
` status = SOS_ErrorResourceAllocation;¬
` }¬
`¬
` /* clean up side effects on error */¬
` if (SOS_FAILED(status)) {¬
` UdpSocketRelease(context);¬
` context = NULL;¬
` }¬
` }¬
`¬
` if (SOS_FAILED(status)) {¬
` closesocket(nativeSocket);¬
` }¬
`¬
`¬
` /* "return" my context */¬
` *Socket = context;¬
` }¬
`¬
` return status;¬
`}¬
`¬
`¬
`¬
`¬
`¬
`static¬
`
`Page 15 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 16/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`651
`652
`653
`654
`655
`656
`657
`658
`659
`660
`…
`661
`662
`663
`664
`665
`666
`667
`668
`669
`670
`671
`672
`673
`674
`675
`676
`677
`678
`679
`680
`681
`682
`683
`684
`685
`686
`687
`688
`689
`690
`691
`692
`693
`694
`
`void¬
`Socket_UdpListenCancelExternal(¬
` void * Parameter¬
`)¬
`{¬
` SOS_ISOCKET_UDP_LISTEN* const listenHandle = Parameter;¬
`¬
` BOOL val = SOS_True;¬
`¬
` /* the socket context will be freed in UdpRecvThread just after this
`call is made */¬
` setsockopt(¬
` listenHandle->Socket.NativeSocket,¬
` SOL_SOCKET,¬
` SO_DONTLINGER,¬
` (const char FAR *)&val,¬
` sizeof(BOOL));¬
`¬
` closesocket(listenHandle->Socket.NativeSocket);¬
`¬
`¬
` /* make sure that UdpRecvThread exits */¬
` WaitForSingleObject(¬
` (HANDLE)listenHandle->Socket.NativeRecvThread,¬
` 10000);¬
`¬
` CloseHandle((HANDLE)listenHandle->Socket.NativeRecvThread);¬
`¬
` UdpSocketRelease((SOS_ISOCKET_UDP*) listenHandle);¬
`}¬
`¬
`/* cancels a listen socket, causing the recv thread to exit */¬
`SOS_STATUS¬
`Socket_UdpListenCancel(¬
` SOS_ISOCKET* Interface,¬
` SOS_ISOCKET_UDP_LISTEN* ListenHandle¬
`)¬
`{¬
` SOS_External_Call(Socket_UdpListenCancelExternal, ListenHandle);¬
` return SOS_Success;¬
`}¬
`¬
`¬
`¬
`/* create a socket bound just to the local port and¬
`
`Page 16 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 17/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`695
`696
`697
`698
`699
`700
`701
`702
`703
`704
`705
`706
`707
`708
`709
`710
`711
`712
`713
`714
`715
`716
`717
`718
`719
`720
`721
`722
`723
`724
`725
`726
`727
`728
`729
`730
`731
`732
`733
`734
`735
`736
`737
`738
`739
`
` start a thread to receive those packets. No¬
` callbacks other than the RecvCallback are registered¬
` here because this socket not going to be closed by¬
` the user except through a call to Socket_UdpListenCancel */¬
`¬
`SOS_STATUS¬
`Socket_UdpListen(¬
` SOS_ISOCKET* Interface,¬
` const SOS_ISOCKET_ADDRESS * SocketAddr,¬
` SOS_ISOCKET_UDP_RECEIVE RecvCallback,¬
` SOS_ISOCKET_UDP_LISTEN ** ListenHandle¬
`)¬
`{¬
` SOS_STATUS status = SOS_Error;¬
`¬
` SOCKET nativeSocket;¬
` struct sockaddr_in saddr_local;¬
` DWORD externalWorkerThreadId;¬
`¬
` if (ListenHandle) {¬
` SOS_ISOCKET_UDP_LISTEN* context = NULL;¬
`¬
` /* set addresses in winsock addr struct */¬
` saddr_local.sin_family = PF_INET;¬
` saddr_local.sin_port = htons(SocketAddr->LocalPort);¬
` saddr_local.sin_addr.s_addr = htonl(INADDR_ANY);¬
`¬
` /* Create a UDP socket */¬
` nativeSocket = socket(PF_INET, SOCK_DGRAM, 0);¬
` if (nativeSocket != INVALID_SOCKET) {¬
`¬
` int ret;¬
`¬
` /* Bind the socket to the local address */¬
` ret = bind(¬
` nativeSocket,¬
` (struct sockaddr*)&saddr_local,¬
` sizeof(saddr_local));¬
` if (ret != SOCKET_ERROR) {¬
`¬
` /* fill my context */¬
` context = (SOS_ISOCKET_UDP_LISTEN *) UdpSocketCreate(¬
` nativeSocket,¬
` RecvCallback,¬
` NULL,¬
`
`Page 17 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 18/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`740
`741
`742
`743
`744
`745
`746
`747
`748
`749
`…
`750
`…
`751
`752
`753
`…
`754
`…
`755
`756
`757
`758
`759
`760
`…
`761
`762
`763
`764
`765
`766
`767
`…
`768
`769
`770
`771
`772
`773
`774
`775
`776
`777
`778
`
` NULL,¬
` SocketAddr,¬
` NULL);¬
`¬
` if (context != NULL) {¬
`¬
` /* Spawn a thread to accept packets */¬
` UdpSocketReference((SOS_ISOCKET_UDP*) context);¬
` context->Socket.NativeRecvThread = _beginthreadex(¬
` NULL, /* no security
`descriptor */¬
` 0, /* default stack size
`*/¬
` UdpRecvThread,¬
` context,¬
` 0, /* no creation flags
`*/¬
` &externalWorkerThreadId /* thread ID out param
`*/¬
` );¬
` if (context->Socket.NativeRecvThread != -1) {¬
` status = SOS_Success;¬
` }¬
` else {¬
` /* release the reference that the thread didn't
`take */¬
` UdpSocketRelease((SOS_ISOCKET_UDP*) context);¬
` status = SOS_ErrorResourceAllocation;¬
` }¬
`¬
`¬
` if (SOS_FAILED(status)) {¬
` /* release the reference that the caller won't get
`*/¬
` UdpSocketRelease((SOS_ISOCKET_UDP*) context);¬
` context = NULL;¬
` }¬
` }¬
`¬
` }¬
` else {¬
` status = ERROR_BIND_FAILED;¬
` }¬
`¬
`¬
`
`Page 18 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 19/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`779
`780
`781
`782
`783
`784
`785
`786
`787
`788
`789
`790
`791
`792
`793
`794
`795
`796
`797
`798
`799
`800
`801
`802
`803
`804
`805
`806
`807
`808
`809
`810
`811
`812
`813
`814
`815
`816
`817
`818
`819
`820
`821
`822
`823
`
` /* undo side effects on error */¬
` if (SOS_FAILED(status)) {¬
` closesocket(nativeSocket);¬
` }¬
` }¬
` else {¬
` status = ERROR_SOCKET_FAILED;¬
` }¬
`¬
` *ListenHandle = context;¬
` }¬
`¬
` return status;¬
`}¬
`¬
`¬
`¬
`static¬
`void¬
`WaitForAndCloseRecvThreadProc(¬
` void * Parameter¬
`)¬
`{¬
` SOS_ISOCKET_UDP* const socket = Parameter;¬
`¬
` WaitForSingleObject(¬
` (HANDLE)socket->NativeRecvThread,¬
` 10000);¬
` CloseHandle((HANDLE)socket->NativeRecvThread);¬
`}¬
`¬
`¬
`/* closes a socket that was created for sending, and causes¬
` the recv thread to exit */¬
`SOS_STATUS¬
`Socket_UdpClose(¬
` SOS_ISOCKET* Interface,¬
` SOS_ISOCKET_UDP* Socket¬
`)¬
`{¬
` if (Socket->UserContext) {¬
`¬
` /* this is not a listen socket */¬
` int ret;¬
`¬
`
`Page 19 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 20/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`824
`…
`825
`826
`827
`828
`…
`829
`830
`831
`832
`833
`834
`835
`836
`837
`838
`839
`840
`841
`842
`843
`844
`845
`846
`847
`848
`849
`850
`851
`852
`853
`854
`855
`856
`857
`858
`859
`860
`861
`862
`863
`864
`865
`866
`
` /* the socket context will be freed in UdpRecvThread just after
`this call is made */¬
` ret = closesocket(Socket->NativeSocket);¬
`¬
` if (!Socket->IsCopy) {¬
` /* switch to an external thread to shut down the recv thread
`*/¬
` SOS_External_Call(WaitForAndCloseRecvThreadProc, Socket);¬
` }¬
` }¬
`¬
` return SOS_Success;¬
`}¬
`¬
`¬
`/* releases a reference on an SOS_ISOCKET_UDP. */¬
`SOS_STATUS¬
`Socket_UdpRelease(¬
` SOS_ISOCKET* Interface,¬
` SOS_ISOCKET_UDP* Socket¬
`)¬
`{¬
` UdpSocketRelease(Socket);¬
`¬
` return SOS_Success;¬
`}¬
`¬
`¬
`/* send an entire datagram on the given socket */¬
`SOS_STATUS¬
`Socket_UdpSend(¬
` SOS_ISOCKET* Interface,¬
` SOS_ISOCKET_UDP* Socket,¬
` void* Buffer,¬
` size_t BufferLen,¬
` SOS_FREEPROC BufferFree¬
`)¬
`{¬
` if (BufferLen) {¬
`¬
` int remotesize;¬
` int ret;¬
`¬
` remotesize = sizeof(Socket->RemoteSockAddr);¬
`¬
`
`Page 20 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 21/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
` ret = sendto(¬
` Socket->NativeSocket,¬
` Buffer,¬
` BufferLen,¬
` 0,¬
` (struct sockaddr*)(&Socket->RemoteSockAddr),¬
` remotesize);¬
`¬
` if (ret == -1) {¬
` HRESULT result;¬
` result = WSAGetLastError();¬
` /* SOS_ASSERT_ASSUMPTION(0,"sendto() failed"); */¬
` }¬
`¬
` BufferFree(Buffer);¬
` }¬
`¬
` return SOS_Success;¬
`}¬
`¬
`
`867
`868
`869
`870
`871
`872
`873
`874
`875
`876
`877
`878
`879
`880
`881
`882
`883
`884
`885
`886
`887
`
`Page 21 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`