| 831 | }; |
| 832 | |
| 833 | function doSend(ex, self, ip, list, address, port, callback) { |
| 834 | const state = self[kStateSymbol]; |
| 835 | |
| 836 | if (ex) { |
| 837 | if (typeof callback === 'function') { |
| 838 | process.nextTick(callback, ex); |
| 839 | return; |
| 840 | } |
| 841 | |
| 842 | process.nextTick(() => self.emit('error', ex)); |
| 843 | return; |
| 844 | } else if (!state.handle) { |
| 845 | return; |
| 846 | } |
| 847 | |
| 848 | if (ip && state.sendBlockList?.check(ip, `ipv${isIP(ip)}`)) { |
| 849 | if (callback) { |
| 850 | process.nextTick(callback, new ERR_IP_BLOCKED(ip)); |
| 851 | } |
| 852 | return; |
| 853 | } |
| 854 | |
| 855 | const req = new SendWrap(); |
| 856 | req.list = list; // Keep reference alive. |
| 857 | req.address = address; |
| 858 | req.port = port; |
| 859 | if (callback) { |
| 860 | req.callback = callback; |
| 861 | req.oncomplete = afterSend; |
| 862 | } |
| 863 | |
| 864 | let err; |
| 865 | if (port) |
| 866 | err = state.handle.send(req, list, list.length, port, ip, !!callback); |
| 867 | else |
| 868 | err = state.handle.send(req, list, list.length, !!callback); |
| 869 | |
| 870 | if (err >= 1) { |
| 871 | // Synchronous finish. The return code is msg_length + 1 so that we can |
| 872 | // distinguish between synchronous success and asynchronous success. |
| 873 | if (callback) |
| 874 | process.nextTick(callback, null, err - 1); |
| 875 | return; |
| 876 | } |
| 877 | |
| 878 | if (err && callback) { |
| 879 | // Don't emit as error, dgram_legacy.js compatibility |
| 880 | const ex = new ExceptionWithHostPort(err, 'send', address, port); |
| 881 | process.nextTick(callback, ex); |
| 882 | } |
| 883 | } |
| 884 | |
| 885 | function afterSend(err, sent) { |
| 886 | if (err) { |