OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ppapi/proxy/udp_socket_resource_base.h" | 5 #include "ppapi/proxy/udp_socket_resource_base.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cstring> | 8 #include <cstring> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 } | 60 } |
61 | 61 |
62 int32_t UDPSocketResourceBase::SetOptionImpl( | 62 int32_t UDPSocketResourceBase::SetOptionImpl( |
63 PP_UDPSocket_Option name, | 63 PP_UDPSocket_Option name, |
64 const PP_Var& value, | 64 const PP_Var& value, |
65 bool check_bind_state, | 65 bool check_bind_state, |
66 scoped_refptr<TrackedCallback> callback) { | 66 scoped_refptr<TrackedCallback> callback) { |
67 if (closed_) | 67 if (closed_) |
68 return PP_ERROR_FAILED; | 68 return PP_ERROR_FAILED; |
69 | 69 |
70 SocketOptionData option_data; | 70 // Check if socket is expected to be bound or not according to the option |
71 switch (name) { | 71 switch (name) { |
72 case PP_UDPSOCKET_OPTION_ADDRESS_REUSE: | 72 case PP_UDPSOCKET_OPTION_ADDRESS_REUSE: |
73 case PP_UDPSOCKET_OPTION_BROADCAST: { | 73 check_bind_state = true; // fallthrough |
74 if ((check_bind_state || name == PP_UDPSOCKET_OPTION_ADDRESS_REUSE) && | 74 case PP_UDPSOCKET_OPTION_BROADCAST: |
75 bind_called_) { | 75 case PP_UDPSOCKET_OPTION_MULTICAST_LOOP: |
| 76 case PP_UDPSOCKET_OPTION_MULTICAST_TTL: |
| 77 case PP_UDPSOCKET_OPTION_MULTICAST_IF: { |
| 78 if (check_bind_state && bind_called_) { |
76 // SetOption should fail in this case in order to give predictable | 79 // SetOption should fail in this case in order to give predictable |
77 // behavior while binding. Note that we use |bind_called_| rather | 80 // behavior while binding. Note that we use |bind_called_| rather |
78 // than |bound_| since the latter is only set on successful completion | 81 // than |bound_| since the latter is only set on successful completion |
79 // of Bind(). | 82 // of Bind(). |
80 return PP_ERROR_FAILED; | 83 return PP_ERROR_FAILED; |
81 } | 84 } |
| 85 break; |
| 86 } |
| 87 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: |
| 88 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: |
| 89 case PP_UDPSOCKET_OPTION_MULTICAST_JOIN: |
| 90 case PP_UDPSOCKET_OPTION_MULTICAST_LEAVE: { |
| 91 if (check_bind_state && !bound_) |
| 92 return PP_ERROR_FAILED; |
| 93 break; |
| 94 } |
| 95 } |
| 96 |
| 97 SocketOptionData option_data; |
| 98 switch (name) { |
| 99 case PP_UDPSOCKET_OPTION_ADDRESS_REUSE: |
| 100 case PP_UDPSOCKET_OPTION_BROADCAST: |
| 101 case PP_UDPSOCKET_OPTION_MULTICAST_LOOP: { |
82 if (value.type != PP_VARTYPE_BOOL) | 102 if (value.type != PP_VARTYPE_BOOL) |
83 return PP_ERROR_BADARGUMENT; | 103 return PP_ERROR_BADARGUMENT; |
84 option_data.SetBool(PP_ToBool(value.value.as_bool)); | 104 option_data.SetBool(PP_ToBool(value.value.as_bool)); |
85 break; | 105 break; |
86 } | 106 } |
87 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: | 107 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: |
88 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: { | 108 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: |
89 if (check_bind_state && !bound_) | 109 case PP_UDPSOCKET_OPTION_MULTICAST_IF: { |
90 return PP_ERROR_FAILED; | |
91 if (value.type != PP_VARTYPE_INT32) | 110 if (value.type != PP_VARTYPE_INT32) |
92 return PP_ERROR_BADARGUMENT; | 111 return PP_ERROR_BADARGUMENT; |
93 option_data.SetInt32(value.value.as_int); | 112 option_data.SetInt32(value.value.as_int); |
94 break; | 113 break; |
95 } | 114 } |
| 115 case PP_UDPSOCKET_OPTION_MULTICAST_TTL: { |
| 116 int32_t ival = value.value.as_int; |
| 117 if (value.type != PP_VARTYPE_INT32 && (ival < 0 || ival > 255)) |
| 118 return PP_ERROR_BADARGUMENT; |
| 119 option_data.SetInt32(ival); |
| 120 break; |
| 121 } |
| 122 case PP_UDPSOCKET_OPTION_MULTICAST_JOIN: |
| 123 case PP_UDPSOCKET_OPTION_MULTICAST_LEAVE: { |
| 124 if (value.type != PP_VARTYPE_RESOURCE) |
| 125 return PP_ERROR_BADARGUMENT; |
| 126 PP_Resource resource = static_cast<PP_Resource>(value.value.as_id); |
| 127 option_data.SetInt32(resource); |
| 128 break; |
| 129 } |
96 default: { | 130 default: { |
97 NOTREACHED(); | 131 NOTREACHED(); |
98 return PP_ERROR_BADARGUMENT; | 132 return PP_ERROR_BADARGUMENT; |
99 } | 133 } |
100 } | 134 } |
101 | 135 |
102 Call<PpapiPluginMsg_UDPSocket_SetOptionReply>( | 136 Call<PpapiPluginMsg_UDPSocket_SetOptionReply>( |
103 BROWSER, | 137 BROWSER, |
104 PpapiHostMsg_UDPSocket_SetOption(name, option_data), | 138 PpapiHostMsg_UDPSocket_SetOption(name, option_data), |
105 base::Bind(&UDPSocketResourceBase::OnPluginMsgSetOptionReply, | 139 base::Bind(&UDPSocketResourceBase::OnPluginMsgSetOptionReply, |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 if (result == PP_OK && !data.empty()) | 387 if (result == PP_OK && !data.empty()) |
354 memcpy(output_buffer, data.c_str(), data.size()); | 388 memcpy(output_buffer, data.c_str(), data.size()); |
355 | 389 |
356 recvfrom_addr_ = addr; | 390 recvfrom_addr_ = addr; |
357 | 391 |
358 return result == PP_OK ? static_cast<int32_t>(data.size()) : result; | 392 return result == PP_OK ? static_cast<int32_t>(data.size()) : result; |
359 } | 393 } |
360 | 394 |
361 } // namespace proxy | 395 } // namespace proxy |
362 } // namespace ppapi | 396 } // namespace ppapi |
OLD | NEW |